+2007-12-28 Christian Persch <chpe@gnome.org>
+
+ * modules/other/gail/Makefile.am:
+ * modules/other/gail/tests/*:
+ * configure.in: Merge tests from standalone gail. Bug #504568.
+
2007-12-28 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkclipboard.c: Make the finalizer work when display is
modules/other/Makefile
modules/other/gail/Makefile
modules/other/gail/libgail-util/Makefile
+modules/other/gail/tests/Makefile
modules/engines/Makefile
modules/engines/pixbuf/Makefile
modules/engines/ms-windows/Makefile
include $(top_srcdir)/Makefile.decl
-SUBDIRS = libgail-util
+SUBDIRS = libgail-util tests
if OS_WIN32
no_undefined = -no-undefined
--- /dev/null
+if OS_WIN32
+no_undefined = -no-undefined
+endif
+
+if !OS_WIN32
+moduledir = $(libdir)/gtk-2.0/modules
+module_LTLIBRARIES = \
+ libferret.la
+endif
+
+noinst_LTLIBRARIES = \
+ libtestaction.la \
+ libtestbutton.la \
+ libtestcombo.la \
+ libtestcomponent.la \
+ libtestimage.la \
+ libtestnotebook.la \
+ libtestobject.la \
+ libtestmenuitem.la \
+ libtestoptionmenu.la \
+ libtestpaned.la \
+ libtestprops.la \
+ libtestselection.la \
+ libteststatusbar.la \
+ libtesttable.la \
+ libtesttext.la \
+ libtesttoplevel.la \
+ libtesttreetable.la \
+ libtestvalues.la
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/gdk \
+ -I$(top_builddir)/gdk \
+ -I$(top_srcdir)/gtk \
+ -I$(top_builddir)/gtk
+
+AM_CFLAGS = \
+ $(GTK_DEP_CFLAGS) \
+ $(GTK_DEBUG_FLAGS)
+
+if !OS_WIN32
+libferret_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ ferret.c
+
+libferret_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libferret_la_LIBADD = \
+ $(GAIL_INET_LIBS)
+endif
+
+libtestaction_la_SOURCES = \
+ testaction.c
+
+libtestaction_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestbutton_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testbutton.c
+
+libtestbutton_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestcombo_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testcombo.c
+
+libtestcombo_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestcomponent_la_SOURCES = \
+ testcomponent.c
+
+libtestcomponent_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestimage_la_SOURCES = \
+ testimage.c
+
+libtestimage_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestmenuitem_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testmenuitem.c
+
+libtestmenuitem_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestnotebook_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testnotebook.c
+
+libtestnotebook_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestobject_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testobject.c
+
+libtestobject_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestoptionmenu_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testoptionmenu.c
+
+libtestoptionmenu_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestpaned_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testpaned.c
+
+libtestpaned_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestprops_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testprops.c
+
+libtestprops_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestselection_la_SOURCES = \
+ testselection.c
+
+libtestselection_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libteststatusbar_la_SOURCES = \
+ teststatusbar.c
+
+libteststatusbar_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtesttable_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testtextlib.c \
+ testtextlib.h \
+ testtable.c
+
+libtesttable_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtesttext_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testtextlib.c \
+ testtextlib.h \
+ testtext.c
+
+libtesttext_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtesttoplevel_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testtoplevel.c
+
+libtesttoplevel_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtesttreetable_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testtreetable.c
+
+libtesttreetable_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestvalues_la_SOURCES = \
+ testvalues.c
+
+libtestvalues_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
--- /dev/null
+
+============================
+GAIL README
+Last Updated: August 2, 2001
+============================
+
+
+General Info
+============
+
+This README describes how to use the various test programs
+in the gail/tests directory.
+
+To run the various test programs described in this README,
+the test libraries must be built and installed. Running
+"make", then "make install" in the gail top-level directory
+will take care of this. Then do the following:
+
+1. Set the environment variable GTK_MODULES to
+ "libgail:lib<testname>"
+
+ For example, for ferret, it would be "libgail:libferret"
+
+2. Run the GTK+ test program specified. These test programs
+ are found in the GTK+ build directory in the subdirectory
+ called "tests".
+
+Most test programs will display output directly to the
+terminal window where the GTK+ test program was launched.
+Some test programs (testtable and testtext) will launch a
+test GUI program which allows more interactive testing.
+
+The test GUI has two windows. The first window is the
+"Test Control" window and the second window is the
+"Test Output" window. In the "Test Control" window,
+press the button(s) that corresponds to the tests to run
+and press the "Run Tests" button at the bottom of the
+screen. Some tests have associated text entry fields
+which become active when the button is toggled on. These
+text entry fields correspond to arguments that affect how
+the test is executed. They are pre-filled with default
+values but the user can change them if desired. The
+output from the tests is displayed in the "Test Output"
+window.
+
+
+testlib
+=======
+
+Contains general purpose functionality that is used by the
+various tests. These include functions that find a specific
+widget/AtkObject in the test program, and functions used by
+tests that use the Gail Test GUI.
+
+
+ferret
+======
+
+Ferret is a passive in-process test tool for ATK and GAIL.
+
+Run a GTK+-2.0 application such as "testgtk", and ferret will
+display a window on screen. In this window accessibility
+information about the GTK+ widgets will appear as they
+receive focus.
+
+The ferret window has several tabs, one for each of the
+following ATK interfaces.
+
+ Object
+ Action
+ Component
+ Image
+ Table
+ Text
+ Value
+
+Tabs that do not apply to the current widget in focus will be
+displayed as inactive. Clicking on an active tab will display
+information about the AtkObject accessed via the ATK API. In the
+Action tab the various actions are displayed as buttons. When
+a button is clicked, the action specified on the button's
+label is performed.
+
+If you have installed the "festival" speech synthesis system,
+running festival in server mode (festival --server) and turning
+on Ferret's Festival support will cause the following to happen:
+
+1. AtkObject accessible names, roles, and keybindings will be
+ spoken as they receive focus.
+2. When the caret (cursor) is moved in a text field, the
+ current line will be spoken, unless the caret is moved
+ just a single character. In the later case, only the
+ single character after the caret will be spoken.
+
+Festival support can be turned on by checking "Festival" in the
+menu, or by setting the environment variable FERRET_FESTIVAL
+prior to starting the test. By checking "Festival Terse" or
+by setting the environment variable FERRET_TERSE, only the
+name of the AtkObject will be spoken (and not the roles and
+keybindings).
+
+A magnifier can be turned on to enlarge the widget in focus
+by checking "Magnifier" in the menu, or by setting the
+environment variable FERRET_MAGNIFIER. This requires that
+the magnifier standalone code is running.
+
+Checking "Track Mouse in the menu or by setting the environment
+variable FERRET_MOUSETRACK causes ferret to display information
+about the widget that is under the mouse rather than the widget
+that has focus. The mouse is tracked via GtkWidget
+"enter_notify_event" signals, so flyweight objects are not tracked.
+
+Checking "Terminal Output" in the menu or by setting the
+environment variable FERRET_ASCII will display the information
+that is normally displayed to the ferret GUI window to the
+terminal screen.
+
+Checking "No ATK Signals" in the menu or by setting the
+environment variable FERRET_NOSIGNALS will cause ferret to
+ignore any ATK signals, and it will not update its display
+when such signals occur.
+
+
+testaction
+==========
+
+This is a GTK+ module used to test the implementation of the ATK
+interface AtkAction, except for atk_action_do_action() in the GAIL
+library. It is normally used with the GTK+ test program testgtk.
+
+
+testbutton
+==========
+
+This is a GTK+ module used to test the accessible implementation
+for buttons. It is normally used with the GTK+ test program testgtk.
+
+Set the TEST_ACCESSIBLE_NAME environment variable to have the test
+driver attach to a widget by widget name (compared via the
+gtk_widget_get_name function call).
+
+Set the environment variable TEST_ACCESSIBLE_AUTO and the program
+will execute the action defined for a GailButton once.
+
+
+testcombo
+=========
+
+This is a GTK+ module used to test the implementation of the ATK action
+interfaces on GailCombo. It is normally used with the GTK+ test program
+testgtk by putting the focus in the GtkCombo in entry window.
+
+
+testcomponent
+=============
+
+This is a GTK+ module used to test the implementation of the ATK
+interface AtkComponent in the GAIL library. It is normally used with the
+GTK+ test program testgtk.
+
+
+testimage
+=========
+
+This is a GTK+ module used to test the implementation of the ATK
+interface AtkImage in the GAIL library. It is normally used with the GTK+
+test program testgtk, but can also be used with testdnd when you want
+to test GtkPixmap. This modules pops up an extra dialog on startup , containing
+GtkArrows and a GtkImage. This dialog has to be closed before control is returned to main window.
+
+
+testmenuitem
+============
+
+This is a GTK+ module used to test the accessible implementation
+for menu items. It is normally used with the GTK+ test program testgtk.
+
+Set the TEST_ACCESSIBLE_NAME environment variable to have the test
+driver attach to a widget by widget name (compared via the
+gtk_widget_get_name function call).
+
+Set the environment variable TEST_ACCESSIBLE_AUTO and the program
+will execute the action defined for a GailButton once.
+
+
+testnotebook
+=============
+
+This is a GTK+ module used to test the implementation of the ATK
+interface AtkSelection for GailNotebook. It is normally used with the
+GTK+ test program testgtk.
+
+
+testobject
+==========
+
+This is a GTK+ module used to test the implementation of the ATK
+interface in atkobject.h in the GAIL library. It is normally used with the
+GTK+ test program testgtk.
+
+
+testoptionmenu
+==============
+
+This is a GTK+ module used to test the implementation of the ATK interfaces
+for GtkOptionmenu. It should be used with the GTK+ test program testgtk and
+its file selection dialog.
+
+
+testpaned
+=========
+
+This is a GTK+ module used to test the implementation of the ATK
+interface AtkValue for GailPaned. It is normally used with the
+GTK+ test program testgtk. It checks the setting of the position
+programmatically and that notification is received if the position
+is changed interactively.
+
+
+testprops
+==========
+
+This is a GTK+ module used to test the implementation of ATK properties
+and property change handlers in the GAIL library. It is normally used with
+the GTK+ test program testgtk. To see the changing of the state
+ATK_STATE_SHOWING use menus in "progress bar". To see the changing of the
+state ATK_STATE_SENSITIVE uses "labels". To see changing of child and parent
+use resize check box in "panes".
+
+Set the TEST_ACCESSIBLE_NAME environment variable to have the test
+driver attach to a widget by widget name (compared via the
+gtk_widget_get_name function call).
+
+
+testselection
+=============
+
+This is a GTK+ module used to test the implementation of the AtkSelection
+interface works for the GAIL library. It is normally used with the GTK+
+test program testgtk and clicking on the menus option. It can also be used
+with the GtkCombo which can be accessed by clicking on the entry option.
+
+
+teststatusbar
+=============
+
+This is a GTK+ module used to test that the text on the statusbar
+can be retrieved using GailStatusbar. It is normally used with the GTK+
+test program testgtk and clicking on statusbar button.
+
+
+testtable
+=========
+
+This is GTK+ module used to test the implementation of AtkTable
+interfaces. It can be used with GailTreeView, for example. It
+can be used with any of the following GTK+ test programs:
+testtreecolumns, testtreefocus, testtreesort, testtreeview,
+or treestoretest.
+
+Set the TEST_ACCESSIBLE_NO_PROPERTIES environment variable
+to not receive information about property values changing
+(like cell state changes).
+
+Set the TEST_ACCESSIBLE_NO_GUI environment variable to run the
+test without the GUI program.
+
+
+testtext
+========
+
+This is a GTK+ module used to test the implementation of AtkText and
+AtkEditableText interfaces on GailTextView. It is normally used with
+the GTK+ test program testtext started with a text file loaded.
+It can also be used with the GTK+ test program testgtk, and then
+click on the "entry" or "label" button.
+
+Set the TEST_ACCESSIBLE_NAME environment variable to have the test
+driver attach to a widget by widget name (compared via the
+gtk_widget_get_name function call).
+
+Set the TEST_ACCESSIBLE_DELAY environment variable to an integer
+and the test driver will attach to only a widget on the nth screen
+that is displayed.
+
+
+testtoplevel
+============
+
+This test exercises the AtkUtil functions. It accesses the
+atk_get_root() toplevel object, sets/removes global listeners,
+and displays the ATK implementation name/version.
+
+Set the TEST_ACCESSIBLE_DEPTH environment variable to control
+how deep the children of the toplevel object are displayed.
+The default is a depth of 2. Specifying a depth of -1 will
+show the complete hierarchy.
+
+
+testvalues
+==========
+
+This is a GTK+ module used to test the implementation of AtkValue interface
+works for the GAIL library. GailProgressbar, GailSpinbutton and GailRange
+can all be tested using this module.
+
+
+GAIL README Authors
+===================
+
+-Brian Cameron (brian.cameron@sun.com)
+-Bill Haneman (bill.haneman@sun.com)
+-Padraig O'Briain (padraig.obriain@sun.com)
+
--- /dev/null
+#define MAX_BUFFER 256
+#define GTK_ENABLE_BROKEN
+#define MAX_GROUPS 20
+#define MAX_NAME_VALUE 20
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <strings.h>
+#include "testlib.h"
+#include "config.h"
+
+typedef enum
+{
+ OBJECT,
+ ACTION,
+ COMPONENT,
+ IMAGE,
+ SELECTION,
+ TABLE,
+ TEXT,
+ VALUE,
+ END_TABS
+} TabNumber;
+
+typedef enum
+{
+ OBJECT_INTERFACE,
+ RELATION_INTERFACE,
+ STATE_INTERFACE,
+ ACTION_INTERFACE,
+ COMPONENT_INTERFACE,
+ IMAGE_INTERFACE,
+ SELECTION_INTERFACE,
+ TABLE_INTERFACE,
+ TEXT_INTERFACE,
+ TEXT_ATTRIBUTES,
+ VALUE_INTERFACE
+} GroupId;
+
+typedef enum
+{
+ VALUE_STRING,
+ VALUE_BOOLEAN,
+ VALUE_TEXT,
+ VALUE_BUTTON
+} ValueType;
+
+/* GUI Information for the group */
+
+typedef struct
+{
+ GroupId group_id;
+ GtkFrame *scroll_outer_frame;
+ GtkWidget *frame;
+ GtkVBox *group_vbox;
+ GtkAdjustment *adj;
+ GList *name_value;
+ gchar *name;
+ gboolean is_scrolled;
+ gint default_height;
+} GroupInfo;
+
+typedef struct
+{
+ GList *groups;
+ GtkWidget *page;
+ GtkWidget *main_box;
+ gchar *name;
+} TabInfo;
+
+typedef struct
+{
+ ValueType type;
+ gboolean active;
+
+ GtkHBox *column1, *column2, *hbox;
+ GtkLabel *label;
+
+ GtkButton *button;
+ GValue button_gval;
+ gulong signal_id;
+ AtkObject *atkobj;
+ gint action_num;
+
+ GtkWidget *string;
+ GtkWidget *boolean;
+ GtkWidget *text;
+} NameValue;
+
+typedef enum {
+ FERRET_SIGNAL_OBJECT,
+ FERRET_SIGNAL_TEXT,
+ FERRET_SIGNAL_TABLE
+} FerretSignalType;
+
+/* Function prototypes */
+
+/* GUI functions */
+
+static void _init_data(void);
+static void _create_window(void);
+static void _add_menu(GtkWidget ** menu, GtkWidget ** menuitem,
+ gchar * name, gboolean init_value, GCallback func);
+static void _clear_tab(TabNumber tab_n);
+static void _greyout_tab (GtkWidget *widget, gboolean is_sensitive);
+static void _finished_group(TabNumber tab_n, gint group_num);
+static gboolean _object_is_ours (AtkObject *aobject);
+static void _create_event_watcher (void);
+
+/* Mouse Watcher/Magnifier/Festival functions */
+
+static gboolean _mouse_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data);
+static gboolean _button_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data);
+static void _send_to_magnifier (gint x, gint y, gint w, gint h);
+static void _send_to_festival (const gchar * name,
+ const gchar * role_name, const gchar * accel);
+static void _speak_caret_event (AtkObject * aobject);
+static void _festival_say (const gchar * text);
+static void _festival_write (const gchar * text, int fd);
+static gint _festival_init (void);
+
+/* Update functions */
+
+static void _update_current_page(GtkNotebook *notebook, gpointer p,
+ guint current_page);
+static void _update(TabNumber top_tab, AtkObject *aobject);
+
+/* Print functions */
+
+static void _print_accessible (AtkObject *aobject);
+
+static gint _print_object (AtkObject *aobject);
+static gint _print_relation (AtkObject *aobject);
+static gint _print_state (AtkObject *aobject);
+
+static gint _print_action (AtkAction *aobject);
+static gint _print_component (AtkComponent *aobject);
+static gint _print_image (AtkImage *aobject);
+static gint _print_selection (AtkSelection *aobject);
+static gint _print_table (AtkTable *aobject);
+static gint _print_text (AtkText *aobject);
+static gint _print_text_attributes (AtkText *aobject);
+static gint _print_value (AtkValue *aobject);
+static void _print_value_type(gint group_num, gchar *type, GValue *value);
+static gint _print_groupname(TabNumber tab_n, GroupId group_id,
+ const char *groupname);
+static NameValue* _print_key_value(TabNumber tab_n, gint group_number,
+ const char *label, gpointer value, ValueType type);
+static void _print_signal(AtkObject *aobject, FerretSignalType type,
+ const char *name, const char *info);
+
+/* Data Access functions */
+
+static GroupInfo* _get_group(TabInfo *tab, GroupId group_id,
+ const gchar *groupname);
+void _get_group_scrolled(GroupInfo *group);
+static NameValue* _get_name_value(GroupInfo *group, const gchar *label,
+ gpointer value, ValueType type);
+
+/* Signal handlers */
+
+static void _update_handlers(AtkObject *obj);
+static void _notify_text_insert_handler (GObject *obj,
+ int position, int offset);
+static void _notify_text_delete_handler (GObject *obj,
+ int position, int offset);
+static void _notify_caret_handler (GObject *obj, int position);
+static void _notify_table_row_inserted (GObject *obj,
+ gint start_offset, gint length);
+static void _notify_table_column_inserted (GObject *obj,
+ gint start_offset, gint length);
+static void _notify_table_row_deleted (GObject *obj,
+ gint start_offset, gint length);
+static void _notify_table_column_deleted (GObject *obj,
+ gint start_offset, gint length);
+static void _notify_table_row_reordered (GObject *obj);
+static void _notify_table_column_reordered (GObject *obj);
+static void _notify_object_child_added (GObject *obj,
+ gint index, AtkObject *child);
+static void _notify_object_child_removed (GObject *obj,
+ gint index, AtkObject *child);
+static void _notify_object_state_change (GObject *obj,
+ gchar *name, gboolean set);
+
+/* Property handlers */
+
+static void _property_change_handler (AtkObject *obj,
+ AtkPropertyValues *values);
+
+/* Ferret GUI callbacks */
+
+void _action_cb(GtkWidget *widget, gpointer *userdata);
+void _toggle_terminal(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data);
+void _toggle_no_signals(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data);
+void _toggle_magnifier(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data);
+void _toggle_festival(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data);
+void _toggle_festival_terse(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data);
+void _toggle_trackmouse(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data);
+void _toggle_trackfocus(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data);
+
+/* Global variables */
+static GtkNotebook *notebook;
+static TabInfo *nbook_tabs[END_TABS];
+static gint mouse_watcher_focus_id = -1;
+static gint mouse_watcher_button_id = -1;
+static gint focus_tracker_id = -1;
+static gboolean use_magnifier = FALSE;
+static gboolean use_festival = FALSE;
+static gboolean track_mouse = FALSE;
+static gboolean track_focus = TRUE;
+static gboolean say_role = TRUE;
+static gboolean say_accel = TRUE;
+static gboolean display_ascii = FALSE;
+static gboolean no_signals = FALSE;
+static gint last_caret_offset = 0;
+
+static AtkObject *last_object = NULL;
+static GtkWidget *mainWindow = NULL;
+static GtkWidget *vbox1 = NULL;
+static GtkWidget *menu = NULL;
+static GtkWidget *menutop = NULL;
+static GtkWidget *menubar = NULL;
+static GtkWidget *menuitem_terminal = NULL;
+static GtkWidget *menuitem_no_signals = NULL;
+static GtkWidget *menuitem_magnifier = NULL;
+static GtkWidget *menuitem_festival = NULL;
+static GtkWidget *menuitem_festival_terse = NULL;
+static GtkWidget *menuitem_trackmouse = NULL;
+static GtkWidget *menuitem_trackfocus = NULL;
+
+#ifdef HAVE_SOCKADDR_UN_SUN_LEN
+static struct sockaddr_un mag_server = { 0, AF_UNIX , "/tmp/magnifier_socket" };
+static struct sockaddr_un client = { 0 , AF_UNIX, "/tmp/mag_client"};
+#else
+static struct sockaddr_un mag_server = { AF_UNIX , "/tmp/magnifier_socket" };
+static struct sockaddr_un client = { AF_UNIX, "/tmp/mag_client"};
+#endif
+
+/* GUI Information for the output window */
+typedef struct
+{
+ GtkWindow *outputWindow;
+ GtkWidget *hbox;
+ GtkWidget *vbox;
+ GtkWidget *label;
+ GtkWidget *textInsert;
+ gchar *testTitle;
+} MainDialog;
+
+static void
+_send_to_magnifier(gint x, gint y, gint w, gint h)
+{
+ int desc, length_msg;
+ gchar buff[100];
+
+ sprintf (buff, "~5:%d,%d", x+w/2, y+h/2);
+
+#ifdef MAG_DEBUG
+ g_print ("sending magnifier: %s\n", buff);
+#endif
+
+#ifdef HAVE_SOCKADDR_UN_SUN_LEN
+ mag_server.sun_len = SUN_LEN(&mag_server);
+ client.sun_len = SUN_LEN(&client);
+#endif
+
+ if((desc=socket(AF_UNIX,SOCK_STREAM,0)) == -1){
+ perror("socket");
+ return;
+ }
+ unlink("/tmp/mag_client");
+
+ if (bind(desc, (struct sockaddr*)&client, sizeof(client)) == -1)
+ {
+ perror("bind");
+ return;
+ }
+
+ if (connect(desc,(struct sockaddr*)&mag_server,sizeof(mag_server)) == -1)
+ {
+ perror("connect");
+ return;
+ }
+
+ length_msg = write(desc,buff,strlen(buff));
+ unlink("/tmp/mag_client");
+ return;
+}
+
+static int _festival_init (void)
+{
+ int fd;
+ struct sockaddr_in name;
+ int tries = 2;
+
+ name.sin_family = AF_INET;
+ name.sin_port = htons (1314);
+ name.sin_addr.s_addr = htonl(INADDR_ANY);
+ fd = socket (PF_INET, SOCK_STREAM, 0);
+
+ while (connect(fd, (struct sockaddr *) &name, sizeof (name)) < 0) {
+ if (!tries--) {
+ perror ("connect");
+ return -1;
+ }
+ }
+
+ _festival_write ("(audio_mode'async)", fd);
+ return fd;
+}
+
+static void _festival_say (const gchar *text)
+{
+ static int fd = 0;
+ gchar *quoted;
+ gchar *p;
+ gchar prefix [100];
+ const gchar *stretch;
+
+ fprintf (stderr, "saying %s\n", text);
+
+ if (!fd)
+ {
+ fd = _festival_init ();
+ }
+
+ quoted = g_malloc(100+strlen(text)*2);
+
+ stretch = g_strdup (g_getenv ("FESTIVAL_STRETCH"));
+ if (!stretch) stretch = "0.75";
+ sprintf (prefix, "(audio_mode'shutup)\n (Parameter.set 'Duration_Stretch %s)\n (SayText \"", stretch);
+
+ strcpy(quoted, prefix);
+ p = quoted + strlen (prefix);
+ while (*text) {
+ if ( *text == '\\' || *text == '"' )
+ *p = '\\';
+ *p++ = *text++;
+ }
+ *p++ = '"';
+ *p++ = ')';
+ *p = 0;
+
+ _festival_write (quoted, fd);
+
+ g_free(quoted);
+}
+
+
+static void _send_to_festival (const gchar *role_name,
+ const gchar *name, const gchar *accel)
+{
+ gchar *string;
+ int len = (strlen (role_name)+1 + strlen (name)+2 + 4 + strlen (accel)+2);
+ int i, j;
+ gchar ch;
+ gchar *accel_name;
+
+ string = (gchar *) g_malloc (len * sizeof (gchar));
+
+ i = 0;
+ if (say_role)
+ {
+ j = 0;
+ while (role_name[j])
+ {
+ ch = role_name[j++];
+ if (ch == '_') ch = ' ';
+ string[i++] = ch;
+ };
+ string[i++] = ' ';
+ }
+ j = 0;
+ while (name[j])
+ {
+ ch = name[j++];
+ if (ch == '_') ch = ' ';
+ string[i++] = ch;
+ };
+ if ((say_accel) && (strlen (accel) > 0))
+ {
+ accel_name = (gchar *)accel;
+ if (strncmp (accel, "<C", 2) == 0)
+ {
+ accel_name = strncpy (accel_name, " control ", 9);
+ }
+ else if (strncmp (accel, " control", 5))
+ {
+ string[i++] = ' ';
+ string[i++] = 'a';
+ string[i++] = 'l';
+ string[i++] = 't';
+ string[i++] = ' ';
+ }
+ j = 0;
+ while (accel_name[j])
+ {
+ ch = accel_name[j++];
+ if (ch == '_') ch = ' ';
+ string[i++] = ch;
+ };
+ }
+ string[i] = '\0';
+
+ _festival_say (string);
+ g_free (string);
+}
+
+static void _festival_write (const gchar *command_string, int fd)
+{
+ if (fd < 0) {
+ perror("socket");
+ return;
+ }
+ write(fd, command_string, strlen(command_string));
+}
+
+static void _speak_caret_event (AtkObject *aobject)
+{
+ gint dummy1, dummy2;
+ gint caret_offset = atk_text_get_caret_offset (ATK_TEXT (aobject));
+ gchar * text;
+
+ if (abs(caret_offset - last_caret_offset) > 1)
+ {
+ text = atk_text_get_text_at_offset (ATK_TEXT (aobject),
+ caret_offset,
+ ATK_TEXT_BOUNDARY_LINE_START,
+ &dummy1,
+ &dummy2);
+ }
+ else
+ {
+ text = atk_text_get_text_before_offset (ATK_TEXT (aobject),
+ caret_offset,
+ ATK_TEXT_BOUNDARY_CHAR,
+ &dummy1,
+ &dummy2);
+ }
+ _festival_say (text);
+ g_free (text);
+ last_caret_offset = caret_offset;
+}
+
+static void
+_greyout_tab (GtkWidget *page_child, gboolean is_sensitive)
+{
+ GtkWidget *tab;
+
+ tab = gtk_notebook_get_tab_label (notebook, page_child);
+ if (tab)
+ gtk_widget_set_sensitive (GTK_WIDGET (tab), is_sensitive);
+}
+
+static void
+_refresh_notebook (AtkObject *aobject)
+{
+ if (ATK_IS_OBJECT (aobject))
+ {
+ _greyout_tab (nbook_tabs[ACTION]->page, ATK_IS_ACTION(aobject));
+ _greyout_tab (nbook_tabs[COMPONENT]->page, ATK_IS_COMPONENT(aobject));
+ _greyout_tab (nbook_tabs[IMAGE]->page, ATK_IS_IMAGE(aobject));
+ _greyout_tab (nbook_tabs[SELECTION]->page, ATK_IS_SELECTION(aobject));
+ _greyout_tab (nbook_tabs[TABLE]->page, ATK_IS_TABLE(aobject));
+ _greyout_tab (nbook_tabs[TEXT]->page, ATK_IS_TEXT(aobject));
+ _greyout_tab (nbook_tabs[VALUE]->page, ATK_IS_VALUE(aobject));
+ }
+}
+
+static void _print_accessible (AtkObject *aobject)
+{
+ TabNumber top_tab;
+
+ if (_object_is_ours(aobject))
+ {
+ if (display_ascii)
+ g_print("\nFocus entered the ferret output window!\n");
+ return;
+ }
+
+ _refresh_notebook(aobject);
+
+ if (display_ascii)
+ g_print("\nFocus change\n");
+
+ /* Do not attach signal handlers if the user has asked not to */
+ if (!no_signals)
+ _update_handlers(aobject);
+ else
+ last_object = aobject; /* _update_handler normally does this */
+
+ top_tab = gtk_notebook_get_current_page (notebook) + OBJECT;
+ _update(top_tab, aobject);
+
+ if (use_magnifier)
+ {
+ gint x, y;
+ gint w=0, h=0;
+
+ if (ATK_IS_TEXT (aobject))
+ {
+ gint x0, y0, w0, h0;
+ gint xN, yN, wN, hN;
+ gint len;
+ len = atk_text_get_character_count (ATK_TEXT (aobject));
+ atk_text_get_character_extents (ATK_TEXT (aobject), 0,
+ &x0, &y0, &w0, &h0,
+ ATK_XY_SCREEN);
+ if (len > 0)
+ {
+ atk_text_get_character_extents (ATK_TEXT (aobject), len-1,
+ &xN, &yN, &wN, &hN,
+ ATK_XY_SCREEN);
+ x = MIN (x0, xN);
+ y = MIN (y0, yN);
+ w = MAX (x0+w0, xN+wN) - x;
+ h = MAX (y0+h0, yN+hN) - y;
+ }
+ else
+ {
+ x = x0;
+ y = y0;
+ }
+ }
+ else if (ATK_IS_COMPONENT (aobject))
+ {
+ atk_component_get_extents (ATK_COMPONENT(aobject),
+ &x, &y, &w, &h,
+ ATK_XY_SCREEN);
+ }
+ if (w > -1) _send_to_magnifier (x, y, w, h);
+ }
+}
+
+static gboolean
+_object_is_ours (AtkObject *aobject)
+{
+ /* determine whether this object is parented by our own accessible... */
+
+ AtkObject *toplevel = aobject;
+
+ while (atk_object_get_role(aobject) != ATK_ROLE_FRAME)
+ {
+ aobject = atk_object_get_parent (aobject);
+ if (aobject == NULL) break;
+ toplevel = aobject;
+ };
+
+ /*
+ * Some widgets do not have an ATK_ROLE_FRAME at the top,
+ * so ignore those.
+ */
+ if (aobject != NULL)
+ {
+ if (GTK_ACCESSIBLE(toplevel)->widget == mainWindow)
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static gchar *
+ferret_get_name_from_container (AtkObject *aobject)
+{
+ gchar *s = NULL;
+ gint n = atk_object_get_n_accessible_children (aobject);
+ gint i = 0;
+
+ while (!s && (i < n))
+ {
+ AtkObject *child;
+ child = atk_object_ref_accessible_child (aobject, i);
+ if (ATK_IS_TEXT (child))
+ {
+ gint count = atk_text_get_character_count (ATK_TEXT (child));
+ s = atk_text_get_text (ATK_TEXT (child),
+ 0,
+ count);
+ }
+ g_object_unref (child);
+ ++i;
+ }
+
+ if (!s)
+ {
+ s = g_strdup ("");
+ }
+ return s;
+}
+
+static gint
+_print_object (AtkObject *aobject)
+{
+ G_CONST_RETURN gchar * parent_name = NULL;
+ G_CONST_RETURN gchar * name = NULL;
+ G_CONST_RETURN gchar * description = NULL;
+ G_CONST_RETURN gchar * typename = NULL;
+ G_CONST_RETURN gchar * parent_typename = NULL;
+ G_CONST_RETURN gchar * role_name = NULL;
+ G_CONST_RETURN gchar * accel_name = NULL;
+ G_CONST_RETURN gchar * text = NULL;
+ AtkRole role;
+ AtkObject *parent = NULL;
+ static AtkObject *prev_aobject = NULL;
+ gint n_children = 0;
+ gint index_in_parent = -1;
+ gchar *output_str;
+ gint group_num;
+ TabNumber tab_n = OBJECT;
+
+ group_num = _print_groupname(tab_n, OBJECT_INTERFACE, "Object Interface");
+
+ name = atk_object_get_name (aobject);
+ typename = g_type_name (G_OBJECT_TYPE (aobject));
+ description = atk_object_get_description (aobject);
+ parent = atk_object_get_parent(aobject);
+ if (parent)
+ index_in_parent = atk_object_get_index_in_parent(aobject);
+ n_children = atk_object_get_n_accessible_children(aobject);
+ role = atk_object_get_role(aobject);
+ role_name = atk_role_get_name(role);
+
+ if (ATK_IS_ACTION (aobject))
+ {
+ accel_name = atk_action_get_keybinding (ATK_ACTION(aobject), 0);
+ if (!accel_name) accel_name = "";
+ }
+ else
+ {
+ accel_name = "";
+ }
+
+ if (GTK_IS_ACCESSIBLE (aobject) &&
+ GTK_IS_WIDGET (GTK_ACCESSIBLE (aobject)->widget))
+ {
+ _print_key_value(tab_n, group_num, "Widget name",
+ (gpointer)gtk_widget_get_name(GTK_ACCESSIBLE (aobject)->widget),
+ VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, "Widget name", "No Widget",
+ VALUE_STRING);
+ }
+
+ if (typename)
+ {
+ _print_key_value(tab_n, group_num, "Accessible Type",
+ (gpointer)typename, VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, "Accessible Type", "NULL",
+ VALUE_STRING);
+ }
+
+ if (name)
+ {
+ _print_key_value(tab_n, group_num, "Accessible Name",
+ (gpointer)name, VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, "Accessible Name", "(unknown)",
+ VALUE_STRING);
+ }
+ if (use_festival)
+ {
+ if (aobject != prev_aobject)
+ {
+ if (ATK_IS_TEXT (aobject) && !name)
+ {
+ text =
+ atk_text_get_text_at_offset (ATK_TEXT (aobject),
+ (gint) 0,
+ ATK_TEXT_BOUNDARY_SENTENCE_END,
+ (gint *) NULL,
+ (gint *) NULL);
+ fprintf (stderr, "first sentence: %s\n", text);
+ _send_to_festival (role_name,
+ text, "");
+ if (!name) name = "no name";
+ }
+ else
+ {
+ text = "";
+ if (!name)
+ {
+ if (atk_object_get_role (aobject) == ATK_ROLE_TABLE_CELL)
+ {
+ gchar *cname = ferret_get_name_from_container (aobject);
+ if (cname) name = g_strdup (cname);
+ }
+ else if (atk_object_get_role (aobject) == ATK_ROLE_CHECK_BOX)
+ {
+ name = g_strdup ("check box");
+ }
+ else
+ {
+ name = "no name";
+ }
+ }
+ _send_to_festival (role_name, name, accel_name);
+ }
+ }
+ }
+
+ if (parent)
+ {
+ parent_name = atk_object_get_name(parent);
+
+ parent_typename = g_type_name (G_OBJECT_TYPE (parent));
+
+ if (parent_typename)
+ {
+ _print_key_value(tab_n, group_num, "Parent Accessible Type",
+ (gpointer)parent_typename, VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num,
+ "Parent Accessible Type", "NULL", VALUE_STRING);
+ }
+
+ if (parent_name)
+ {
+ _print_key_value(tab_n, group_num, "Parent Accessible Name",
+ (gpointer)parent_name, VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num,
+ "Parent Accessible Name", "NULL", VALUE_STRING);
+ }
+
+ output_str = g_strdup_printf("%d", index_in_parent);
+ _print_key_value(tab_n, group_num, "Index in Parent",
+ (gpointer)output_str, VALUE_STRING);
+ g_free(output_str);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, "Parent", "NULL", VALUE_STRING);
+ }
+
+ if (description)
+ {
+ _print_key_value(tab_n, group_num, "Accessible Description",
+ (gpointer)description, VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num,
+ "Accessible Description", "NULL", VALUE_STRING);
+ }
+
+ if (role_name)
+ {
+ _print_key_value(tab_n, group_num, "Accessible Role", (gpointer)role_name,
+ VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, "Accessible Role", "NULL",
+ VALUE_STRING);
+ }
+
+ output_str = g_strdup_printf("%d", n_children);
+ _print_key_value(tab_n, group_num, "Number Children", (gpointer)output_str,
+ VALUE_STRING);
+ g_free(output_str);
+ prev_aobject = aobject;
+
+ return(group_num);
+}
+
+static gint
+_print_relation (AtkObject *aobject)
+{
+ AtkRelationSet* relation_set = atk_object_ref_relation_set (aobject);
+ gint n_relations = atk_relation_set_get_n_relations (relation_set);
+ gint group_num;
+ TabNumber tab_n = OBJECT;
+
+ group_num = _print_groupname(tab_n, RELATION_INTERFACE,
+ "Relation Interface");
+
+ if (relation_set)
+ {
+ AtkRelation * relation;
+ G_CONST_RETURN gchar * relation_name = NULL;
+ G_CONST_RETURN gchar * relation_obj_name = NULL;
+ AtkRelationType relation_type;
+ AtkObject *relation_obj;
+ GPtrArray * relation_arry;
+ gchar *label_str;
+ gchar *output_str;
+ gint i, j;
+
+ output_str = g_strdup_printf("%d", n_relations);
+ _print_key_value(tab_n, group_num,
+ "Number of Relations", (gpointer)output_str, VALUE_STRING);
+ g_free(output_str);
+
+ for (i = 0; i < n_relations; i++)
+ {
+ relation = atk_relation_set_get_relation (relation_set, i);
+
+ relation_type = atk_relation_get_relation_type (relation);
+ relation_name = atk_relation_type_get_name (relation_type);
+
+ relation_arry = atk_relation_get_target(relation);
+
+ if (relation_name)
+ {
+ label_str = g_strdup_printf("Relation %d Name", i + 1);
+ _print_key_value(tab_n, group_num, label_str,
+ (gpointer)relation_name, VALUE_STRING);
+ g_free(label_str);
+ }
+ else
+ {
+ label_str = g_strdup_printf("Relation %d Type", i + 1);
+ output_str = g_strdup_printf("%d", relation_type);
+ _print_key_value(tab_n, group_num, label_str,
+ (gpointer)output_str, VALUE_STRING);
+ g_free(label_str);
+ g_free(output_str);
+ }
+
+ label_str = g_strdup_printf("Relation %d with", i + 1);
+ output_str = g_strdup_printf("%d AtkObjects", relation_arry->len);
+ _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
+ VALUE_STRING);
+ g_free(label_str);
+ g_free(output_str);
+
+ for (j=0; j < relation_arry->len; j++)
+ {
+ label_str = g_strdup_printf(
+ "Relation %d,%d with AtkObject Name", i + 1, j + 1);
+ relation_obj = (AtkObject *)
+ g_ptr_array_index(relation_arry, j);
+ relation_obj_name = atk_object_get_name(relation_obj);
+
+ _print_key_value(tab_n, group_num, label_str,
+ (gpointer)relation_obj_name, VALUE_STRING);
+ g_free(label_str);
+ }
+ }
+
+ g_object_unref (relation_set);
+ }
+ return(group_num);
+}
+
+static gint
+_print_state (AtkObject *aobject)
+{
+ AtkStateSet *state_set = atk_object_ref_state_set(aobject);
+ gint group_num;
+ TabNumber tab_n = OBJECT;
+ static AtkStateType states_to_track[] =
+ {
+ ATK_STATE_ACTIVE,
+ ATK_STATE_CHECKED,
+ ATK_STATE_EXPANDED,
+ ATK_STATE_EXPANDABLE,
+ ATK_STATE_SELECTED,
+ ATK_STATE_SHOWING,
+ ATK_STATE_VISIBLE
+ };
+
+ group_num = _print_groupname(tab_n, STATE_INTERFACE,
+ "State Interface");
+
+ if (state_set)
+ {
+ gboolean boolean_value;
+ AtkStateType one_state;
+ G_CONST_RETURN gchar *name;
+ gint i;
+
+ for (i=0; i < sizeof(states_to_track)/sizeof(AtkStateType); i++)
+ {
+ one_state = (AtkStateType) states_to_track[i];
+ name = atk_state_type_get_name (one_state);
+
+ if (name)
+ {
+ boolean_value =
+ atk_state_set_contains_state (state_set, one_state);
+ _print_key_value(tab_n, group_num, name,
+ (gpointer)(&boolean_value), VALUE_BOOLEAN);
+ }
+ }
+ }
+
+ g_object_unref (state_set);
+ return(group_num);
+}
+
+static gint
+_print_action (AtkAction *aobject)
+{
+ G_CONST_RETURN gchar *action_name;
+ G_CONST_RETURN gchar *action_description;
+ G_CONST_RETURN gchar *action_keybinding;
+ gchar *label_str, *output_str;
+ gint group_num;
+ gint num_actions, j;
+ TabNumber tab_n = ACTION;
+ NameValue *nv;
+
+ group_num = _print_groupname(tab_n, ACTION_INTERFACE,
+ "Action Interface");
+
+ num_actions = atk_action_get_n_actions (aobject);
+ output_str = g_strdup_printf("%d", num_actions);
+ _print_key_value(tab_n, group_num, "Number of Actions",
+ (gpointer) output_str, VALUE_STRING);
+ g_free(output_str);
+
+ for (j = 0; j < num_actions; j++)
+ {
+ label_str = g_strdup_printf("Action %d Name", j + 1);
+ action_name = atk_action_get_name (aobject, j);
+ if (action_name)
+ {
+ nv = _print_key_value(tab_n, group_num, label_str,
+ (gpointer) action_name, VALUE_BUTTON);
+ }
+ else
+ {
+ nv = _print_key_value(tab_n, group_num, label_str, "NULL",
+ VALUE_BUTTON);
+ }
+
+ nv->atkobj = ATK_OBJECT(aobject);
+ nv->action_num = j;
+ nv->signal_id = g_signal_connect (GTK_OBJECT (nv->button),
+ "clicked", GTK_SIGNAL_FUNC (_action_cb), nv);
+
+ g_free(label_str);
+
+ label_str = g_strdup_printf("Action %d Description", j + 1);
+ action_description = atk_action_get_description (aobject, j);
+ if (action_description)
+ {
+ _print_key_value(tab_n, group_num, label_str,
+ (gpointer)action_description, VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, label_str, "NULL",
+ VALUE_STRING);
+ }
+ g_free(label_str);
+
+ label_str = g_strdup_printf("Action %d Keybinding", j + 1);
+ action_keybinding = atk_action_get_keybinding (aobject, j);
+ if (action_keybinding)
+ {
+ _print_key_value(tab_n, group_num, label_str,
+ (gpointer)action_keybinding, VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, label_str, "NULL",
+ VALUE_STRING);
+ }
+ g_free(label_str);
+ }
+ return(group_num);
+}
+
+static gint
+_print_component (AtkComponent *aobject)
+{
+ gchar *output_str;
+ gint x = 0;
+ gint y = 0;
+ gint width = 0;
+ gint height = 0;
+ gint group_num;
+ TabNumber tab_n = COMPONENT;
+
+ group_num = _print_groupname(tab_n, COMPONENT_INTERFACE,
+ "Component Interface");
+
+ atk_component_get_extents (aobject,
+ &x, &y, &width, &height, ATK_XY_SCREEN);
+
+ output_str = g_strdup_printf("x: %d y: %d width: %d height %d",
+ x, y, width, height);
+ _print_key_value(tab_n, group_num, "Geometry", (gpointer)output_str,
+ VALUE_STRING);
+ g_free(output_str);
+ return(group_num);
+}
+
+static gint
+_print_image (AtkImage *aobject)
+{
+ G_CONST_RETURN gchar *image_desc;
+ gchar *output_str;
+ gint x = 0;
+ gint y = 0;
+ gint height = 0;
+ gint width = 0;
+ gint group_num;
+ TabNumber tab_n = IMAGE;
+
+ group_num = _print_groupname(tab_n, IMAGE_INTERFACE,
+ "Image Interface");
+
+ image_desc = atk_image_get_image_description(aobject);
+ if (image_desc)
+ {
+ _print_key_value(tab_n, group_num, "Description", (gpointer)image_desc,
+ VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, "Description", "NULL",
+ VALUE_STRING);
+ }
+
+ atk_image_get_image_position(aobject, &x, &y, ATK_XY_SCREEN);
+ atk_image_get_image_size(aobject, &height, &width);
+
+ output_str = g_strdup_printf("x: %d y: %d width: %d height %d",
+ x, y, width, height);
+ _print_key_value(tab_n, group_num, "Geometry", (gpointer)output_str,
+ VALUE_STRING);
+ g_free(output_str);
+ return(group_num);
+}
+
+static gint
+_print_selection (AtkSelection *aobject)
+{
+ AtkObject *object;
+ AtkRole role;
+ gchar *label_str, *output_str;
+ gint group_num;
+ gint n_selected, j, n_selectable;
+ TabNumber tab_n = SELECTION;
+
+ group_num = _print_groupname(tab_n, SELECTION_INTERFACE,
+ "Selection Interface");
+
+ n_selected = atk_selection_get_selection_count (aobject);
+ output_str = g_strdup_printf ("%d", n_selected);
+ _print_key_value (tab_n, group_num, "Number of Selected Children",
+ (gpointer) output_str, VALUE_STRING);
+ g_free (output_str);
+ /*
+ * The number of selected items is the number of children except for
+ * a ComboBox where it is the number of items in the list.
+ */
+ object = ATK_OBJECT (aobject);
+ role = atk_object_get_role (object);
+ if (role == ATK_ROLE_COMBO_BOX)
+ {
+ object = atk_object_ref_accessible_child (object, 0);
+ g_return_val_if_fail (atk_object_get_role (object) == ATK_ROLE_LIST,
+ group_num);
+ n_selectable = atk_object_get_n_accessible_children (object);
+ g_object_unref (G_OBJECT (object));
+ }
+ else
+ {
+ n_selectable = atk_object_get_n_accessible_children (object);
+ }
+ output_str = g_strdup_printf ("%d", n_selectable);
+ _print_key_value (tab_n, group_num, "Number of Selectable Children",
+ (gpointer) output_str, VALUE_STRING);
+ g_free (output_str);
+
+ for (j = 0; j < n_selected; j++)
+ {
+ G_CONST_RETURN gchar *selected_name;
+ AtkObject *selected_object;
+
+ selected_object = atk_selection_ref_selection (aobject, j);
+ selected_name = atk_object_get_name (selected_object);
+ if (selected_name == NULL)
+ {
+ selected_name = "No name";
+ }
+ label_str = g_strdup_printf ("Selected item: %d Name", j+1);
+ _print_key_value (tab_n, group_num, label_str,
+ (gpointer) selected_name, VALUE_STRING);
+ g_free (label_str);
+ g_object_unref (G_OBJECT (selected_object));
+ }
+ return group_num;
+}
+
+static gint
+_print_table (AtkTable *aobject)
+{
+ gchar *label_str, *output_str;
+ G_CONST_RETURN gchar *col_desc;
+ AtkObject *caption;
+ gint n_cols, n_rows;
+ gint i;
+ gint group_num;
+ TabNumber tab_n = TABLE;
+
+ group_num = _print_groupname(tab_n, TABLE_INTERFACE,
+ "Table Interface");
+
+ n_cols = atk_table_get_n_columns(aobject);
+ output_str = g_strdup_printf("%d", n_cols);
+ _print_key_value(tab_n, group_num, "Number Columns", (gpointer)output_str,
+ VALUE_STRING);
+ g_free(output_str);
+
+ n_rows = atk_table_get_n_rows(aobject);
+ output_str = g_strdup_printf("%d", n_rows);
+ _print_key_value(tab_n, group_num, "Number Rows", (gpointer)output_str,
+ VALUE_STRING);
+ g_free(output_str);
+
+ caption = atk_table_get_caption(aobject);
+ if (caption)
+ {
+ G_CONST_RETURN gchar* caption_name;
+
+ caption_name = atk_object_get_name (caption);
+ if (caption_name)
+ {
+ _print_key_value(tab_n, group_num, "Caption Name",
+ (gpointer)caption_name, VALUE_STRING);
+ }
+ }
+
+ for (i=0; i < n_cols; i++)
+ {
+ label_str = g_strdup_printf("Column %d Description", i + 1);
+
+ col_desc = atk_table_get_column_description(aobject, i);
+ if (col_desc)
+ {
+ _print_key_value(tab_n, group_num, label_str, (gpointer)col_desc,
+ VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, label_str, "NULL",
+ VALUE_STRING);
+ }
+
+ g_free(label_str);
+ }
+
+ return(group_num);
+}
+
+static gint
+_print_text (AtkText *aobject)
+{
+ gchar *output_str, *text_val, *text_val_escaped;
+ gint n_chars, caret_offset;
+ gint start_offset, end_offset;
+ gint group_num;
+ gint x, y, w, h;
+ TabNumber tab_n = TEXT;
+
+ group_num = _print_groupname(tab_n, TEXT_INTERFACE,
+ "Text Content");
+
+ n_chars = atk_text_get_character_count(aobject);
+
+ output_str = g_strdup_printf("%d", n_chars);
+ _print_key_value(tab_n, group_num, "Total Character Count",
+ (gpointer)output_str, VALUE_STRING);
+ g_free(output_str);
+
+ /*
+ * Pass through g_strescape so that non-ASCII chars are made
+ * print-able.
+ */
+ text_val = atk_text_get_text (aobject, 0, n_chars);
+ if (text_val)
+ {
+ text_val_escaped = g_strescape(text_val, NULL);
+ _print_key_value (tab_n, group_num, "Text", (gpointer)text_val_escaped,
+ VALUE_TEXT);
+ g_free (text_val);
+ g_free (text_val_escaped);
+ }
+ else
+ {
+ _print_key_value (tab_n, group_num, "Text", "NULL", VALUE_TEXT);
+ }
+
+ caret_offset = atk_text_get_caret_offset(aobject);
+ output_str = g_strdup_printf("%d", caret_offset);
+ _print_key_value(tab_n, group_num, "Caret Offset", (gpointer)output_str,
+ VALUE_STRING);
+ g_free(output_str);
+
+ if (caret_offset < 0)
+ return(group_num);
+
+ text_val = atk_text_get_text_at_offset (aobject, caret_offset,
+ ATK_TEXT_BOUNDARY_CHAR,
+ &start_offset, &end_offset);
+ if (text_val)
+ {
+ text_val_escaped = g_strescape(text_val, NULL);
+ _print_key_value(tab_n, group_num, "Current Character",
+ (gpointer)text_val_escaped, VALUE_STRING);
+ g_free (text_val);
+ g_free (text_val_escaped);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, "Current Character", "none",
+ VALUE_STRING);
+ }
+
+ atk_text_get_character_extents (aobject, caret_offset,
+ &x, &y, &w, &h, ATK_XY_SCREEN);
+ output_str = g_strdup_printf ("(%d, %d) (%d, %d)", x, y, w, h);
+ if (output_str)
+ {
+ _print_key_value(tab_n, group_num, "Character Bounds (screen)",
+ (gpointer)output_str, VALUE_STRING);
+ g_free(output_str);
+ }
+
+ atk_text_get_character_extents (aobject, caret_offset,
+ &x, &y, &w, &h, ATK_XY_WINDOW);
+ output_str = g_strdup_printf ("(%d, %d) (%d, %d)", x, y, w, h);
+ if (output_str)
+ {
+ _print_key_value(tab_n, group_num, "Character Bounds (window)",
+ (gpointer)output_str, VALUE_STRING);
+ g_free(output_str);
+ }
+
+ text_val = atk_text_get_text_at_offset (aobject, caret_offset,
+ ATK_TEXT_BOUNDARY_WORD_START,
+ &start_offset, &end_offset);
+ if (text_val)
+ {
+ text_val_escaped = g_strescape(text_val, NULL);
+ _print_key_value(tab_n, group_num, "Current Word",
+ (gpointer)text_val_escaped, VALUE_STRING);
+ g_free (text_val);
+ g_free (text_val_escaped);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, "Current Word", "none",
+ VALUE_STRING);
+ }
+
+ text_val = atk_text_get_text_at_offset (aobject, caret_offset,
+ ATK_TEXT_BOUNDARY_LINE_START,
+ &start_offset, &end_offset);
+ if (text_val)
+ {
+ text_val_escaped = g_strescape(text_val, NULL);
+ _print_key_value(tab_n, group_num, "Current Line",
+ (gpointer)text_val_escaped, VALUE_STRING);
+ g_free (text_val);
+ g_free (text_val_escaped);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, "Current Line", "none",
+ VALUE_STRING);
+ }
+
+ text_val = atk_text_get_text_at_offset (aobject, caret_offset,
+ ATK_TEXT_BOUNDARY_SENTENCE_START,
+ &start_offset, &end_offset);
+ if (text_val)
+ {
+ text_val_escaped = g_strescape(text_val, NULL);
+ _print_key_value(tab_n, group_num, "Current Sentence",
+ (gpointer)text_val_escaped, VALUE_STRING);
+ g_free (text_val);
+ g_free (text_val_escaped);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, "Current Line", "none",
+ VALUE_STRING);
+ }
+ return(group_num);
+}
+
+static gint
+_print_text_attributes (AtkText *aobject)
+{
+ AtkAttributeSet *attribute_set;
+ AtkAttribute *attribute;
+ gchar *output_str, *label_str;
+ gint start_offset, end_offset, caret_offset;
+ gint attribute_set_len, attribute_offset, i;
+ gint n_chars;
+ gint group_num;
+ TabNumber tab_n = TEXT;
+
+ n_chars = atk_text_get_character_count(aobject);
+
+ group_num = _print_groupname (tab_n, TEXT_ATTRIBUTES,
+ "Text Attributes at Caret");
+
+ caret_offset = atk_text_get_caret_offset(aobject);
+ attribute_offset = caret_offset;
+
+ start_offset = 0;
+ end_offset = 0;
+
+ attribute_set = atk_text_get_run_attributes(aobject, attribute_offset,
+ &start_offset, &end_offset);
+
+ label_str = g_strdup_printf("Attribute run start");
+
+ output_str = g_strdup_printf("%d", start_offset);
+ _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
+ VALUE_STRING);
+ g_free(label_str);
+ g_free(output_str);
+
+ label_str = g_strdup_printf("Attribute run end");
+ output_str = g_strdup_printf("%d", end_offset);
+ _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
+ VALUE_STRING);
+ g_free(label_str);
+ g_free(output_str);
+
+ if (attribute_set == NULL)
+ attribute_set_len = 0;
+ else
+ attribute_set_len = g_slist_length(attribute_set);
+
+ label_str = g_strdup_printf("Number of Attributes");
+ output_str = g_strdup_printf("%d", attribute_set_len);
+ _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
+ VALUE_STRING);
+ g_free(label_str);
+ g_free(output_str);
+
+ for (i=0; i < attribute_set_len; i++)
+ {
+ attribute = ((AtkAttribute *) g_slist_nth(attribute_set, i)->data);
+
+ _print_key_value(tab_n, group_num, attribute->name,
+ (gpointer)attribute->value, VALUE_STRING);
+ }
+ if (attribute_set != NULL)
+ atk_attribute_set_free(attribute_set);
+
+
+ return(group_num);
+}
+
+static gint
+_print_value (AtkValue *aobject)
+{
+ GValue *value_back, val;
+ gint group_num;
+ TabNumber tab_n = VALUE;
+
+ value_back = &val;
+
+ group_num = _print_groupname(tab_n, VALUE_INTERFACE,
+ "Value Interface");
+
+ atk_value_get_current_value(aobject, value_back);
+ _print_value_type(group_num, "Value", value_back);
+ atk_value_get_minimum_value(aobject, value_back);
+ _print_value_type(group_num, "Minimum Value", value_back);
+ atk_value_get_maximum_value(aobject, value_back);
+ _print_value_type(group_num, "Maximum Value", value_back);
+ return(group_num);
+}
+
+static void
+_print_value_type(gint group_num, gchar *type, GValue *value)
+{
+ gchar *label_str = NULL;
+ gchar *output_str = NULL;
+ TabNumber tab_n = VALUE;
+
+ if (G_VALUE_HOLDS_DOUBLE (value))
+ {
+ label_str = g_strdup_printf("%s - Double", type);
+ output_str = g_strdup_printf("%f",
+ g_value_get_double (value));
+ _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
+ VALUE_STRING);
+ }
+ else if (G_VALUE_HOLDS_INT (value))
+ {
+ label_str = g_strdup_printf("%s - Integer", type);
+ output_str = g_strdup_printf("%d",
+ g_value_get_int (value));
+ _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
+ VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, "Value", "Unknown Type",
+ VALUE_STRING);
+ }
+
+ if (label_str)
+ g_free(label_str);
+ if (output_str)
+ g_free(output_str);
+}
+
+static void
+_create_event_watcher (void)
+{
+ focus_tracker_id = atk_add_focus_tracker (_print_accessible);
+
+ if (track_mouse)
+ {
+ mouse_watcher_focus_id =
+ atk_add_global_event_listener(_mouse_watcher,
+ "Gtk:GtkWidget:enter_notify_event");
+ mouse_watcher_button_id =
+ atk_add_global_event_listener(_button_watcher,
+ "Gtk:GtkWidget:button_press_event");
+ }
+}
+
+static gboolean
+_mouse_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GObject *object;
+ GtkWidget *widget;
+
+ object = g_value_get_object (param_values + 0);
+
+ if (GTK_IS_MENU(object)) return TRUE;
+
+ g_assert (GTK_IS_WIDGET(object));
+
+ widget = GTK_WIDGET (object);
+ if (GTK_IS_WINDOW (widget))
+ {
+ GtkWidget *focus_widget = GTK_WINDOW (widget)->focus_widget;
+ if (focus_widget != NULL)
+ widget = focus_widget;
+ }
+
+ _print_accessible (gtk_widget_get_accessible (widget));
+ return TRUE;
+}
+
+static gboolean
+_button_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GObject *object;
+ GtkWidget *widget;
+
+ object = g_value_get_object (param_values + 0);
+
+ widget = GTK_WIDGET (object);
+ if (GTK_IS_CONTAINER (widget))
+ {
+ if (G_VALUE_HOLDS_BOXED (param_values + 1))
+ {
+ GdkEventButton *event;
+ gpointer gp;
+ AtkObject *aobject;
+ AtkObject *child;
+ gint aobject_x, aobject_y;
+ gint x, y;
+
+ gp = g_value_get_boxed (param_values + 1);
+ event = (GdkEventButton *) gp;
+ aobject = gtk_widget_get_accessible (widget);
+ aobject_x = aobject_y = 0;
+ atk_component_get_position (ATK_COMPONENT (aobject),
+ &aobject_x, &aobject_y,
+ ATK_XY_WINDOW);
+ x = aobject_x + (gint) event->x;
+ y = aobject_y + (gint) event->y;
+ child = atk_component_ref_accessible_at_point (ATK_COMPONENT (aobject),
+ x,
+ y,
+ ATK_XY_WINDOW);
+ if (child)
+ {
+ _print_accessible (child);
+ g_object_unref (child);
+ }
+ else
+ {
+ if (!GTK_IS_MENU_ITEM (widget))
+ {
+ g_print ("No child at position %d %d for %s\n",
+ x,
+ y,
+ g_type_name (G_OBJECT_TYPE (widget)));
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+static void _add_notebook_page (GtkNotebook *nbook,
+ GtkWidget *content_widget,
+ GtkWidget **new_page,
+ const gchar *label_text)
+{
+ GtkWidget *label;
+
+ if (content_widget != NULL)
+ {
+ *new_page = content_widget;
+ }
+ else
+ {
+ *new_page = gtk_vpaned_new ();
+ }
+
+ label = gtk_label_new ("");
+ gtk_label_set_markup_with_mnemonic (GTK_LABEL (label), label_text);
+ gtk_notebook_append_page (notebook, *new_page, label);
+ gtk_widget_show(*new_page);
+}
+
+static void
+_create_notebook (void)
+{
+ TabInfo *tab;
+ notebook = GTK_NOTEBOOK (gtk_notebook_new());
+
+ tab = nbook_tabs[OBJECT];
+ _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Object</b>");
+
+ tab = nbook_tabs[ACTION];
+ _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Action</b>");
+
+ tab = nbook_tabs[COMPONENT];
+ _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Component</b>");
+
+ tab = nbook_tabs[IMAGE];
+ _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Image</b>");
+
+ tab = nbook_tabs[SELECTION];
+ _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Selection</b>");
+
+ tab = nbook_tabs[TABLE];
+ _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Table</b>");
+
+ tab = nbook_tabs[TEXT];
+ _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>Te_xt</b>");
+
+ tab = nbook_tabs[VALUE];
+ _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Value</b>");
+
+ g_signal_connect (GTK_OBJECT (notebook),
+ "switch-page",
+ GTK_SIGNAL_FUNC (_update_current_page),
+ NULL);
+}
+
+static void
+_init_data(void)
+{
+ TabInfo *the_tab;
+
+ the_tab = g_new0(TabInfo, 1);
+ the_tab->page = NULL;
+ the_tab->main_box = gtk_vbox_new(FALSE, 20);
+ the_tab->name = "Object";
+ nbook_tabs[OBJECT] = the_tab;
+
+ the_tab = g_new0(TabInfo, 1);
+ the_tab->page = NULL;
+ the_tab->main_box = gtk_vbox_new(FALSE, 20);
+ the_tab->name = "Action";
+ nbook_tabs[ACTION] = the_tab;
+
+ the_tab = g_new0(TabInfo, 1);
+ the_tab->page = NULL;
+ the_tab->main_box = gtk_vbox_new(FALSE, 20);
+ the_tab->name = "Component";
+ nbook_tabs[COMPONENT] = the_tab;
+
+ the_tab = g_new0(TabInfo, 1);
+ the_tab->page = NULL;
+ the_tab->main_box = gtk_vbox_new(FALSE, 20);
+ the_tab->name = "Image";
+ nbook_tabs[IMAGE] = the_tab;
+
+ the_tab = g_new0(TabInfo, 1);
+ the_tab->page = NULL;
+ the_tab->main_box = gtk_vbox_new(FALSE, 20);
+ the_tab->name = "Selection";
+ nbook_tabs[SELECTION] = the_tab;
+
+ the_tab = g_new0(TabInfo, 1);
+ the_tab->page = NULL;
+ the_tab->main_box = gtk_vbox_new(FALSE, 20);
+ the_tab->name = "Table";
+ nbook_tabs[TABLE] = the_tab;
+
+ the_tab = g_new0(TabInfo, 1);
+ the_tab->page = NULL;
+ the_tab->main_box = gtk_vbox_new(FALSE, 20);
+ the_tab->name = "Text";
+ nbook_tabs[TEXT] = the_tab;
+
+ the_tab = g_new0(TabInfo, 1);
+ the_tab->page = NULL;
+ the_tab->main_box = gtk_vbox_new(FALSE, 20);
+ the_tab->name = "Value";
+ nbook_tabs[VALUE] = the_tab;
+}
+
+static void
+_create_window (void)
+{
+ static GtkWidget *window = NULL;
+
+ if (!window)
+ {
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_widget_set_name (window, "Ferret Window");
+ gtk_window_set_policy (GTK_WINDOW(window), TRUE, TRUE, FALSE);
+
+ g_signal_connect (GTK_OBJECT (window), "destroy",
+ GTK_SIGNAL_FUNC (gtk_widget_destroyed),
+ &window);
+
+ gtk_window_set_title (GTK_WINDOW (window), "GTK+ Ferret Output");
+ gtk_window_set_default_size (GTK_WINDOW (window), 333, 550);
+ gtk_container_set_border_width (GTK_CONTAINER (window), 0);
+
+ vbox1 = gtk_vbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (window), vbox1);
+ gtk_widget_show (vbox1);
+
+ menubar = gtk_menu_bar_new ();
+ gtk_box_pack_start (GTK_BOX (vbox1), menubar, FALSE, TRUE, 0);
+ gtk_widget_show (menubar);
+ menutop = gtk_menu_item_new_with_label("Menu");
+ gtk_menu_bar_append(GTK_MENU_BAR(menubar), menutop);
+ gtk_widget_show (menutop);
+ menu = gtk_menu_new();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (menutop), menu);
+ gtk_widget_show (menu);
+
+ _add_menu(&menu, &menuitem_trackmouse, "Track Mouse", track_mouse,
+ GTK_SIGNAL_FUNC(_toggle_trackmouse));
+ _add_menu(&menu, &menuitem_trackfocus, "Track Focus", track_focus,
+ GTK_SIGNAL_FUNC(_toggle_trackfocus));
+ _add_menu(&menu, &menuitem_magnifier, "Magnifier", use_magnifier,
+ GTK_SIGNAL_FUNC(_toggle_magnifier));
+ _add_menu(&menu, &menuitem_festival, "Festival", use_festival,
+ GTK_SIGNAL_FUNC(_toggle_festival));
+ _add_menu(&menu, &menuitem_festival_terse, "Festival Terse",
+ (!say_role && !say_accel),
+ GTK_SIGNAL_FUNC(_toggle_festival_terse));
+ _add_menu(&menu, &menuitem_terminal, "Terminal Output", display_ascii,
+ GTK_SIGNAL_FUNC(_toggle_terminal));
+ _add_menu(&menu, &menuitem_no_signals, "No ATK Signals", no_signals,
+ GTK_SIGNAL_FUNC(_toggle_no_signals));
+
+ _create_notebook ();
+ gtk_container_add (GTK_CONTAINER (vbox1), GTK_WIDGET (notebook));
+ gtk_widget_show (GTK_WIDGET (notebook));
+ }
+ if (!GTK_WIDGET_VISIBLE (window))
+ gtk_widget_show (window);
+
+ mainWindow = GTK_WIDGET (window);
+}
+
+static void
+_add_menu(GtkWidget ** menu, GtkWidget ** menuitem, gchar * name,
+ gboolean init_value, GCallback func)
+{
+ *menuitem = gtk_check_menu_item_new_with_label(name);
+ gtk_check_menu_item_set_active(
+ GTK_CHECK_MENU_ITEM(*menuitem), init_value);
+ gtk_menu_shell_append (GTK_MENU_SHELL (*menu), *menuitem);
+ gtk_widget_show(*menuitem);
+ g_signal_connect(GTK_OBJECT(*menuitem), "toggled", func, NULL);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ if (g_getenv ("FERRET_ASCII"))
+ display_ascii = TRUE;
+
+ if (g_getenv ("FERRET_NOSIGNALS"))
+ no_signals = TRUE;
+
+ if (display_ascii)
+ g_print("GTK ferret Module loaded\n");
+
+ if (g_getenv("FERRET_MAGNIFIER"))
+ use_magnifier = TRUE;
+
+ if (g_getenv ("FERRET_FESTIVAL"))
+ use_festival = TRUE;
+
+ if (g_getenv ("FERRET_MOUSETRACK"))
+ track_mouse = TRUE;
+
+ if (g_getenv ("FERRET_TERSE"))
+ {
+ say_role = FALSE;
+ say_accel = FALSE;
+ }
+
+ _init_data();
+
+ _create_window();
+
+ _create_event_watcher();
+
+ return 0;
+}
+
+static void
+_clear_tab(TabNumber tab_n)
+{
+ GList *group_list, *nv_list;
+ TabInfo *tab;
+ GroupInfo *group;
+ NameValue *nv;
+
+ tab = nbook_tabs[tab_n];
+
+ for (group_list = tab->groups; group_list; group_list = group_list->next)
+ {
+ group = (GroupInfo *) group_list->data;
+
+ if (group->is_scrolled)
+ gtk_widget_hide(GTK_WIDGET(group->scroll_outer_frame));
+
+ gtk_widget_hide(GTK_WIDGET(group->frame));
+ gtk_widget_hide(GTK_WIDGET(group->group_vbox));
+
+ for (nv_list = group->name_value; nv_list; nv_list = nv_list->next)
+ {
+ nv = (NameValue *) nv_list->data;
+ nv->active = FALSE;
+ gtk_widget_hide(GTK_WIDGET(nv->column1));
+ gtk_widget_hide(GTK_WIDGET(nv->column2));
+ gtk_widget_hide(GTK_WIDGET(nv->label));
+
+ switch (nv->type)
+ {
+ case VALUE_STRING:
+ gtk_widget_hide(GTK_WIDGET(nv->string));
+ break;
+ case VALUE_BOOLEAN:
+ gtk_widget_hide(GTK_WIDGET(nv->boolean));
+ break;
+ case VALUE_TEXT:
+ gtk_widget_hide(GTK_WIDGET(nv->text));
+ break;
+ case VALUE_BUTTON:
+ gtk_widget_hide(GTK_WIDGET(nv->button));
+ break;
+ }
+ gtk_widget_hide(GTK_WIDGET(nv->hbox));
+
+ /* Disconnect signal handler if any */
+ if (nv->signal_id != -1)
+ g_signal_handler_disconnect(nv->button, nv->signal_id);
+
+ nv->signal_id = -1;
+ }
+ }
+}
+
+static gint
+_print_groupname(TabNumber tab_n, GroupId group_id,
+ const char *groupname)
+{
+ TabInfo *tab;
+ GroupInfo *the_group;
+ gint rc = -1;
+
+ if (display_ascii)
+ g_print("\n<%s>\n", groupname);
+
+ tab = nbook_tabs[tab_n];
+ the_group = _get_group(tab, group_id, groupname);
+ rc = g_list_index(tab->groups, the_group);
+ return rc;
+}
+
+static GroupInfo*
+_get_group(TabInfo *tab, GroupId group_id, const gchar *groupname)
+{
+ GroupInfo *group = NULL;
+ gboolean found = FALSE;
+ GList *group_list;
+
+ for (group_list = tab->groups; group_list; group_list = group_list->next)
+ {
+ group = (GroupInfo *) group_list->data;
+ if (group_id == group->group_id)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ /* build a new one */
+ group = (GroupInfo *)g_new0(GroupInfo, 1);
+ group->group_id = group_id;
+ _get_group_scrolled(group);
+
+ if (group->is_scrolled)
+ {
+ group->frame = gtk_scrolled_window_new (NULL, NULL);
+ gtk_widget_set_usize(GTK_WIDGET(group->frame), -2,
+ group->default_height);
+ group->scroll_outer_frame = GTK_FRAME(gtk_frame_new(groupname));
+ gtk_container_add(GTK_CONTAINER(group->scroll_outer_frame),
+ group->frame);
+ }
+ else
+ {
+ group->frame = gtk_frame_new(groupname);
+ }
+
+ gtk_container_set_border_width(GTK_CONTAINER(group->frame), 10);
+
+ group->name = g_strdup(groupname);
+ group->group_vbox = GTK_VBOX(gtk_vbox_new(FALSE, 10));
+
+ if (group->is_scrolled)
+ {
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (group->frame),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_add_with_viewport(
+ GTK_SCROLLED_WINDOW(group->frame),
+ GTK_WIDGET(group->group_vbox));
+ }
+ else
+ {
+ gtk_container_add(GTK_CONTAINER(group->frame),
+ GTK_WIDGET(group->group_vbox));
+ }
+
+ tab->groups = g_list_append (tab->groups, group);
+
+ if (group->is_scrolled)
+ {
+ gtk_box_pack_start_defaults(GTK_BOX(tab->main_box),
+ GTK_WIDGET(group->scroll_outer_frame));
+ }
+ else
+ {
+ gtk_box_pack_start_defaults(GTK_BOX(tab->main_box),
+ GTK_WIDGET(group->frame));
+ }
+ }
+
+ return group;
+}
+
+void
+_get_group_scrolled(GroupInfo *group)
+{
+ if (group->group_id == OBJECT_INTERFACE)
+ {
+ group->is_scrolled = FALSE;
+ }
+ else if (group->group_id == RELATION_INTERFACE)
+ {
+ group->is_scrolled = TRUE;
+ group->default_height = 50;
+ }
+ else if (group->group_id == STATE_INTERFACE)
+ {
+ group->is_scrolled = TRUE;
+ group->default_height = 100;
+ }
+ else if (group->group_id == ACTION_INTERFACE)
+ {
+ group->is_scrolled = TRUE;
+ group->default_height = 200;
+ }
+ else if (group->group_id == TEXT_ATTRIBUTES)
+ {
+ group->is_scrolled = TRUE;
+ group->default_height = 70;
+ }
+ else
+ {
+ group->is_scrolled = FALSE;
+ }
+}
+
+NameValue *
+_get_name_value(GroupInfo *group, const gchar *label,
+ gpointer value_ptr, ValueType type)
+{
+ NameValue *name_value = NULL;
+ GList *nv_list;
+ GValue *value;
+ gboolean found = FALSE;
+ static char *empty_string = "";
+
+ if (!label)
+ {
+ label = empty_string;
+ }
+
+ for (nv_list = group->name_value; nv_list; nv_list = nv_list->next)
+ {
+ name_value = (NameValue *) nv_list->data;
+ if (!name_value->active)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ name_value = (NameValue *)g_new0(NameValue, 1);
+ name_value->column1 = GTK_HBOX(gtk_hbox_new(FALSE, 10));
+ name_value->column2 = GTK_HBOX(gtk_hbox_new(FALSE, 10));
+ name_value->hbox = GTK_HBOX(gtk_hbox_new(FALSE, 5));
+ name_value->label = GTK_LABEL(gtk_label_new(label));
+ name_value->string = gtk_label_new (NULL);
+ name_value->boolean = gtk_check_button_new ();
+ name_value->text = gtk_entry_new_with_max_length (1000);
+ name_value->button = GTK_BUTTON(gtk_button_new ());
+
+ gtk_box_pack_end(GTK_BOX(name_value->column1),
+ GTK_WIDGET(name_value->label), FALSE, FALSE, 10);
+
+ switch (type)
+ {
+ case VALUE_STRING:
+ gtk_label_set_text(GTK_LABEL(name_value->string),
+ (gchar *) value_ptr);
+ gtk_box_pack_start(GTK_BOX(name_value->column2),
+ GTK_WIDGET(name_value->string), FALSE, FALSE, 10);
+ break;
+ case VALUE_BOOLEAN:
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(name_value->boolean),
+ *((gboolean *)value_ptr));
+ gtk_widget_set_sensitive(name_value->boolean, FALSE);
+ gtk_box_pack_start(GTK_BOX(name_value->column2),
+ GTK_WIDGET(name_value->boolean), FALSE, FALSE, 10);
+ break;
+ case VALUE_TEXT:
+ gtk_entry_set_text (GTK_ENTRY (name_value->text),
+ (gchar *)value_ptr);
+ gtk_box_pack_start(GTK_BOX(name_value->column2),
+ GTK_WIDGET(name_value->text), FALSE, FALSE, 10);
+ case VALUE_BUTTON:
+ value = &(name_value->button_gval);
+ memset (value, 0, sizeof (GValue));
+ g_value_init (value, G_TYPE_STRING);
+ g_value_set_string (value, (gchar *)value_ptr);
+ g_object_set_property(G_OBJECT(name_value->button),
+ "label", value);
+ gtk_box_pack_start(GTK_BOX(name_value->column2),
+ GTK_WIDGET(name_value->button), FALSE, FALSE, 10);
+ break;
+ }
+
+ gtk_box_pack_start_defaults(GTK_BOX(name_value->hbox),
+ GTK_WIDGET(name_value->column1));
+ gtk_box_pack_start_defaults(GTK_BOX(name_value->hbox),
+ GTK_WIDGET(name_value->column2));
+ gtk_container_add(GTK_CONTAINER(group->group_vbox),
+ GTK_WIDGET(name_value->hbox));
+ group->name_value = g_list_append (group->name_value, name_value);
+ }
+ else
+ {
+ gtk_label_set_text(GTK_LABEL(name_value->label), label);
+ switch (type)
+ {
+ case VALUE_STRING:
+ gtk_label_set_text(GTK_LABEL(name_value->string),
+ (gchar *) value_ptr);
+ break;
+ case VALUE_BOOLEAN:
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(name_value->boolean),
+ *((gboolean *)value_ptr));
+ gtk_widget_set_sensitive(name_value->boolean, FALSE);
+ break;
+ case VALUE_TEXT:
+ gtk_entry_set_text (GTK_ENTRY (name_value->text),
+ (gchar *) value_ptr);
+ break;
+ case VALUE_BUTTON:
+ value = &(name_value->button_gval);
+ memset (value, 0, sizeof (GValue));
+ g_value_init (value, G_TYPE_STRING);
+ g_value_set_string (value, (gchar *)value_ptr);
+ g_object_set_property(G_OBJECT(name_value->button),
+ "label", value);
+ break;
+ }
+ }
+
+ name_value->active = TRUE;
+ name_value->type = type;
+ name_value->signal_id = -1;
+
+ gtk_widget_show(GTK_WIDGET(name_value->label));
+
+ switch (type)
+ {
+ case VALUE_STRING:
+ gtk_widget_show(GTK_WIDGET(name_value->string));
+ break;
+ case VALUE_BOOLEAN:
+ gtk_widget_show(GTK_WIDGET(name_value->boolean));
+ break;
+ case VALUE_TEXT:
+ gtk_widget_show(GTK_WIDGET(name_value->text));
+ break;
+ case VALUE_BUTTON:
+ gtk_widget_show(GTK_WIDGET(name_value->button));
+ break;
+ }
+
+ gtk_widget_show(GTK_WIDGET(name_value->column1));
+ gtk_widget_show(GTK_WIDGET(name_value->column2));
+ gtk_widget_show(GTK_WIDGET(name_value->hbox));
+ gtk_widget_show(GTK_WIDGET(group->group_vbox));
+
+ return name_value;
+}
+
+static NameValue *
+_print_key_value(TabNumber tab_n, gint group_number,
+ const char *label, gpointer value, ValueType type)
+{
+ TabInfo *tab;
+ GroupInfo *the_group;
+
+ if (display_ascii)
+ {
+ if (type == VALUE_BOOLEAN)
+ {
+ if (*((gboolean *)value))
+ g_print("\t%-30s\tTRUE\n", label);
+ else
+ g_print("\t%-30s\tFALSE\n", label);
+ }
+ else
+ {
+ g_print("\t%-30s\t%s\n", label,
+ value ? (gchar *)value : "NULL");
+ }
+ }
+
+ tab = nbook_tabs[tab_n];
+ the_group = (GroupInfo *)g_list_nth_data(tab->groups, group_number);
+ return _get_name_value(the_group, label, (gpointer)value, type);
+}
+
+static void
+_finished_group(TabNumber tab_no, gint group_number)
+{
+ TabInfo *tab;
+ GroupInfo *the_group;
+
+ tab = nbook_tabs[tab_no];
+
+ the_group = (GroupInfo *)g_list_nth_data(tab->groups, group_number);
+
+ if (the_group->is_scrolled)
+ gtk_widget_show(GTK_WIDGET(the_group->scroll_outer_frame));
+
+ gtk_widget_show(GTK_WIDGET(the_group->frame));
+ gtk_widget_show(GTK_WIDGET(the_group->group_vbox));
+ gtk_widget_show(GTK_WIDGET(tab->main_box));
+}
+
+/* Signal handlers */
+
+static gulong child_added_id = 0;
+static gulong child_removed_id = 0;
+static gulong state_change_id = 0;
+
+static gulong text_caret_handler_id = 0;
+static gulong text_inserted_id = 0;
+static gulong text_deleted_id = 0;
+
+static gulong table_row_inserted_id = 0;
+static gulong table_column_inserted_id = 0;
+static gulong table_row_deleted_id = 0;
+static gulong table_column_deleted_id = 0;
+static gulong table_row_reordered_id = 0;
+static gulong table_column_reordered_id = 0;
+
+static gulong property_id = 0;
+
+static void
+_update_handlers(AtkObject *obj)
+{
+ /* Remove signal handlers from object that had focus before */
+
+ if (last_object != NULL && G_TYPE_CHECK_INSTANCE(last_object))
+ {
+ if (child_added_id != 0)
+ g_signal_handler_disconnect(last_object, child_added_id);
+ if (child_removed_id != 0)
+ g_signal_handler_disconnect(last_object, child_removed_id);
+ if (state_change_id != 0)
+ g_signal_handler_disconnect(last_object, state_change_id);
+
+ if (text_caret_handler_id != 0)
+ g_signal_handler_disconnect(last_object, text_caret_handler_id);
+ if (text_inserted_id != 0)
+ g_signal_handler_disconnect(last_object, text_inserted_id);
+ if (text_deleted_id != 0)
+ g_signal_handler_disconnect(last_object, text_deleted_id);
+
+ if (table_row_inserted_id != 0)
+ g_signal_handler_disconnect(last_object, table_row_inserted_id);
+ if (table_column_inserted_id != 0)
+ g_signal_handler_disconnect(last_object, table_column_inserted_id);
+ if (table_row_deleted_id != 0)
+ g_signal_handler_disconnect(last_object, table_row_deleted_id);
+ if (table_column_deleted_id != 0)
+ g_signal_handler_disconnect(last_object, table_column_deleted_id);
+ if (table_row_reordered_id != 0)
+ g_signal_handler_disconnect(last_object, table_row_reordered_id);
+ if (table_column_reordered_id != 0)
+ g_signal_handler_disconnect(last_object, table_column_reordered_id);
+ if (property_id != 0)
+ g_signal_handler_disconnect(last_object, property_id);
+
+ g_object_unref(last_object);
+ }
+
+ last_object = NULL;
+
+ child_added_id = 0;
+ child_removed_id = 0;
+ text_caret_handler_id = 0;
+ text_inserted_id = 0;
+ text_deleted_id = 0;
+ table_row_inserted_id = 0;
+ table_column_inserted_id = 0;
+ table_row_deleted_id = 0;
+ table_column_deleted_id = 0;
+ table_row_reordered_id = 0;
+ table_column_reordered_id = 0;
+ property_id = 0;
+
+ if (!G_TYPE_CHECK_INSTANCE(obj))
+ return;
+
+ g_object_ref(obj);
+ last_object = obj;
+
+ /* Add signal handlers to object that now has focus. */
+
+ if (ATK_IS_OBJECT(obj))
+ {
+ child_added_id = g_signal_connect_closure (obj,
+ "children_changed::add",
+ g_cclosure_new (G_CALLBACK (_notify_object_child_added),
+ NULL, NULL), FALSE);
+
+ child_removed_id = g_signal_connect_closure (obj,
+ "children_changed::remove",
+ g_cclosure_new (G_CALLBACK (_notify_object_child_removed),
+ NULL, NULL), FALSE);
+
+ state_change_id = g_signal_connect_closure (obj,
+ "state_change",
+ g_cclosure_new (G_CALLBACK (_notify_object_state_change),
+ NULL, NULL), FALSE);
+ }
+
+ if (ATK_IS_TEXT(obj))
+ {
+ text_caret_handler_id = g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("text_caret_moved", G_OBJECT_TYPE (obj)),
+ 0, g_cclosure_new (G_CALLBACK (_notify_caret_handler),
+ NULL, NULL), FALSE);
+ text_inserted_id = g_signal_connect_closure (obj,
+ "text_changed::insert",
+ g_cclosure_new (G_CALLBACK (_notify_text_insert_handler),
+ NULL, NULL), FALSE);
+ text_deleted_id = g_signal_connect_closure (obj,
+ "text_changed::delete",
+ g_cclosure_new (G_CALLBACK (_notify_text_delete_handler),
+ NULL, NULL), FALSE);
+ }
+
+ if (ATK_IS_TABLE(obj))
+ {
+ table_row_inserted_id = g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("row_inserted", G_OBJECT_TYPE (obj)),
+ 0, g_cclosure_new (G_CALLBACK (_notify_table_row_inserted),
+ NULL, NULL), FALSE);
+ table_column_inserted_id = g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("column_inserted", G_OBJECT_TYPE (obj)),
+ 0, g_cclosure_new (G_CALLBACK (_notify_table_column_inserted),
+ NULL, NULL), FALSE);
+ table_row_deleted_id = g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("row_deleted", G_OBJECT_TYPE (obj)),
+ 0, g_cclosure_new (G_CALLBACK (_notify_table_row_deleted),
+ NULL, NULL), FALSE);
+ table_column_deleted_id = g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("column_deleted", G_OBJECT_TYPE (obj)),
+ 0, g_cclosure_new (G_CALLBACK (_notify_table_column_deleted),
+ NULL, NULL), FALSE);
+ table_row_reordered_id = g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("row_reordered", G_OBJECT_TYPE (obj)),
+ 0, g_cclosure_new (G_CALLBACK (_notify_table_row_reordered),
+ NULL, NULL), FALSE);
+ table_column_reordered_id = g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("column_reordered", G_OBJECT_TYPE (obj)),
+ 0, g_cclosure_new (G_CALLBACK (_notify_table_column_reordered),
+ NULL, NULL), FALSE);
+ }
+
+ property_id = g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("property_change", G_OBJECT_TYPE (obj)),
+ 0, g_cclosure_new (G_CALLBACK (_property_change_handler),
+ NULL, NULL),
+ FALSE);
+}
+
+/* Text signals */
+
+static void
+_notify_text_insert_handler (GObject *obj, int position, int offset)
+{
+ gchar *text = atk_text_get_text (ATK_TEXT (obj), position, position + offset);
+ gchar *output_str = g_strdup_printf("position %d, length %d text: %s",
+ position, offset, text ? text: "<NULL>");
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TEXT,
+ "Text Insert", output_str);
+ g_free(output_str);
+}
+
+static void
+_notify_text_delete_handler (GObject *obj, int position, int offset)
+{
+ gchar *text = atk_text_get_text (ATK_TEXT (obj), position, position + offset);
+ gchar *output_str = g_strdup_printf("position %d, length %d text: %s",
+ position, offset, text ? text: "<NULL>");
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TEXT,
+ "Text Delete", output_str);
+ g_free(output_str);
+}
+
+static void
+_notify_caret_handler (GObject *obj, int position)
+{
+ gchar *output_str = g_strdup_printf("position %d", position);
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TEXT,
+ "Text Caret Moved", output_str);
+ g_free(output_str);
+}
+
+/* Table signals */
+
+static void
+_notify_table_row_inserted (GObject *obj, gint start_offset,
+ gint length)
+{
+ gchar *output_str =
+ g_strdup_printf("position %d, num of rows inserted %d!\n",
+ start_offset, length);
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
+ "Table Row Inserted", output_str);
+ g_free(output_str);
+}
+
+static void
+_notify_table_column_inserted (GObject *obj, gint start_offset,
+ gint length)
+{
+ gchar *output_str =
+ g_strdup_printf("position %d, num of rows inserted %d!\n",
+ start_offset, length);
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
+ "Table Column Inserted", output_str);
+ g_free(output_str);
+}
+
+static void
+_notify_table_row_deleted (GObject *obj, gint start_offset,
+ gint length)
+{
+ gchar *output_str = g_strdup_printf("position %d, num of rows inserted %d!\n",
+ start_offset, length);
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
+ "Table Row Deleted", output_str);
+ g_free(output_str);
+}
+
+static void
+_notify_table_column_deleted (GObject *obj, gint start_offset,
+ gint length)
+{
+ gchar *output_str = g_strdup_printf("position %d, num of rows inserted %d!\n",
+ start_offset, length);
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
+ "Table Column Deleted", output_str);
+ g_free(output_str);
+}
+
+static void
+_notify_table_row_reordered (GObject *obj)
+{
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
+ "Table Row Reordered", NULL);
+}
+
+static void
+_notify_table_column_reordered (GObject *obj)
+{
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
+ "Table Column Reordered", NULL);
+}
+
+/* Object signals */
+
+static void
+_notify_object_child_added (GObject *obj, gint index,
+ AtkObject *child)
+{
+ gchar *output_str = g_strdup_printf("index %d", index);
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_OBJECT,
+ "Child Added", output_str);
+ g_free(output_str);
+}
+
+static void
+_notify_object_child_removed (GObject *obj, gint index,
+ AtkObject *child)
+{
+ gchar *output_str = g_strdup_printf("index %d", index);
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_OBJECT,
+ "Child Removed", output_str);
+ g_free(output_str);
+}
+
+static void
+_notify_object_state_change (GObject *obj, gchar *name, gboolean set)
+{
+ gchar *output_str = g_strdup_printf("name %s %s set",
+ name, set ? "is" : "was");
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_OBJECT,
+ "State Change", output_str);
+ g_free(output_str);
+}
+
+
+/* Function to print signals */
+
+static void
+_print_signal(AtkObject *aobject, FerretSignalType type,
+ const char *name, const char *info)
+{
+ TabNumber top_tab = gtk_notebook_get_current_page (notebook) + OBJECT;
+
+ if (no_signals)
+ return;
+
+ if (display_ascii)
+ {
+ if (info != NULL)
+ g_print("SIGNAL:\t%-34s\t%s\n", name, info);
+ else
+ g_print("SIGNAL:\t%-34s\n", name);
+ }
+
+ if (use_festival)
+ {
+ if ((type == FERRET_SIGNAL_TEXT) && (!strncmp(name, "Text Caret", 10)))
+ {
+ _speak_caret_event (aobject);
+ }
+ else if (type == FERRET_SIGNAL_TEXT)
+ {
+ last_caret_offset = atk_text_get_caret_offset (ATK_TEXT (aobject));
+ }
+ }
+
+ if (use_magnifier && ATK_IS_TEXT (aobject) &&
+ (type == FERRET_SIGNAL_TEXT) && (!strncmp(name, "Text Caret", 10)))
+ {
+ gint x, y, w, h;
+ gint caret_offset = atk_text_get_caret_offset (ATK_TEXT (aobject));
+ atk_text_get_character_extents ( ATK_TEXT (aobject), caret_offset, &x, &y, &w, &h, ATK_XY_SCREEN);
+ _send_to_magnifier (x, y, w, h);
+ }
+
+ if ((type == FERRET_SIGNAL_TEXT && top_tab == TEXT) ||
+ (type == FERRET_SIGNAL_TABLE && top_tab == TABLE) ||
+ (type == FERRET_SIGNAL_OBJECT && top_tab == OBJECT))
+ {
+ if (display_ascii)
+ g_print("Updating tab\n");
+
+ _update(top_tab, aobject);
+ }
+}
+
+/* Update functions */
+
+static void
+_update (TabNumber top_tab, AtkObject *aobject)
+{
+ gint group_num;
+
+ if (top_tab >= OBJECT && top_tab < END_TABS)
+ {
+ _clear_tab(top_tab);
+ }
+
+ if (top_tab == OBJECT && ATK_IS_OBJECT(aobject))
+ {
+ group_num = _print_object(aobject);
+ _finished_group(OBJECT, group_num);
+ group_num = _print_relation(aobject);
+ _finished_group(OBJECT, group_num);
+ group_num = _print_state(aobject);
+ _finished_group(OBJECT, group_num);
+ }
+ if (top_tab == TEXT && ATK_IS_TEXT(aobject))
+ {
+ group_num = _print_text(ATK_TEXT (aobject));
+ _finished_group(TEXT, group_num);
+ group_num = _print_text_attributes(ATK_TEXT (aobject));
+ _finished_group(TEXT, group_num);
+ }
+ if (top_tab == SELECTION && ATK_IS_SELECTION(aobject))
+ {
+ group_num = _print_selection(ATK_SELECTION (aobject));
+ _finished_group(SELECTION, group_num);
+ }
+ if (top_tab == TABLE && ATK_IS_TABLE(aobject))
+ {
+ group_num = _print_table(ATK_TABLE (aobject));
+ _finished_group(TABLE, group_num);
+ }
+ if (top_tab == ACTION && ATK_IS_ACTION(aobject))
+ {
+ group_num = _print_action(ATK_ACTION (aobject));
+ _finished_group(ACTION, group_num);
+ }
+ if (top_tab == COMPONENT && ATK_IS_COMPONENT(aobject))
+ {
+ group_num = _print_component(ATK_COMPONENT(aobject));
+ _finished_group(COMPONENT, group_num);
+ }
+ if (top_tab == IMAGE && ATK_IS_IMAGE(aobject))
+ {
+ group_num = _print_image(ATK_IMAGE (aobject));
+ _finished_group(IMAGE, group_num);
+ }
+ if (top_tab == VALUE && ATK_IS_VALUE(aobject))
+ {
+ group_num = _print_value(ATK_VALUE(aobject));
+ _finished_group(VALUE, group_num);
+ }
+}
+
+static void
+_update_current_page(GtkNotebook *notebook, gpointer p, guint current_page)
+{
+ _update(current_page+OBJECT, last_object);
+}
+
+/* Property listeners */
+
+static void _property_change_handler (AtkObject *obj,
+ AtkPropertyValues *values)
+{
+ TabNumber top_tab = gtk_notebook_get_current_page (notebook) + OBJECT;
+
+ if (no_signals)
+ return;
+
+ /*
+ * Only process if the property change corrisponds to the current
+ * object
+ */
+ if (obj != last_object)
+ {
+ if (display_ascii)
+ {
+ g_print("\nProperty change event <%s> for object not in focus\n",
+ values->property_name);
+ }
+
+ return;
+ }
+
+ if (display_ascii)
+ {
+ g_print("\nProperty change event <%s> occurred.\n",
+ values->property_name);
+ }
+
+ /*
+ * Update the top tab if a property changes.
+ *
+ * We may be able to ignore some property changes if they do not
+ * change anything in ferret.
+ */
+
+ if (top_tab == OBJECT &&
+ ((strcmp (values->property_name, "accessible-name") == 0) ||
+ (strcmp (values->property_name, "accessible-description") == 0) ||
+ (strcmp (values->property_name, "accessible-parent") == 0) ||
+ (strcmp (values->property_name, "accessible-value") == 0) ||
+ (strcmp (values->property_name, "accessible-role") == 0) ||
+ (strcmp (values->property_name, "accessible-component-layout") == 0) ||
+ (strcmp (values->property_name, "accessible-component-mdi-zorder") == 0) ||
+ (strcmp (values->property_name, "accessible-table-caption") == 0) ||
+ (strcmp (values->property_name,
+ "accessible-table-column-description") == 0) ||
+ (strcmp (values->property_name,
+ "accessible-table-column-header") == 0) ||
+ (strcmp (values->property_name,
+ "accessible-table-row-description") == 0) ||
+ (strcmp (values->property_name,
+ "accessible-table-row-header") == 0) ||
+ (strcmp (values->property_name, "accessible-table-summary") == 0)))
+ {
+ if (display_ascii)
+ g_print("Updating tab\n");
+
+ _update(top_tab, last_object);
+ }
+ else if (top_tab == VALUE &&
+ (strcmp (values->property_name, "accessible-value") == 0))
+ {
+ if (display_ascii)
+ g_print("Updating tab\n");
+
+ _update(top_tab, last_object);
+ }
+}
+
+/* Action button callback function */
+
+void _action_cb(GtkWidget *widget, gpointer *userdata)
+{
+ NameValue *nv = (NameValue *)userdata;
+ atk_action_do_action(ATK_ACTION(nv->atkobj), nv->action_num);
+}
+
+/* Menu-bar callback functions */
+
+void _toggle_terminal(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data)
+{
+ if (checkmenuitem->active)
+ display_ascii = TRUE;
+ else
+ display_ascii = FALSE;
+}
+
+void _toggle_no_signals(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data)
+{
+ if (checkmenuitem->active)
+ no_signals = TRUE;
+ else
+ no_signals = FALSE;
+}
+
+void _toggle_magnifier(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data)
+{
+ if (checkmenuitem->active)
+ use_magnifier = TRUE;
+ else
+ use_magnifier = FALSE;
+}
+
+void _toggle_festival(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data)
+{
+ if (checkmenuitem->active)
+ use_festival = TRUE;
+ else
+ use_festival = FALSE;
+}
+
+void _toggle_festival_terse(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data)
+{
+ if (checkmenuitem->active)
+ {
+ say_role = FALSE;
+ say_accel = FALSE;
+ }
+ else
+ {
+ say_role = TRUE;
+ say_accel = TRUE;
+ }
+}
+
+void _toggle_trackmouse(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data)
+{
+ if (checkmenuitem->active)
+ {
+ mouse_watcher_focus_id =
+ atk_add_global_event_listener(_mouse_watcher,
+ "Gtk:GtkWidget:enter_notify_event");
+ mouse_watcher_button_id =
+ atk_add_global_event_listener(_button_watcher,
+ "Gtk:GtkWidget:button_press_event");
+ track_mouse = TRUE;
+ }
+ else
+ {
+ if (mouse_watcher_focus_id != -1)
+ {
+ atk_remove_global_event_listener(mouse_watcher_focus_id);
+ atk_remove_global_event_listener(mouse_watcher_button_id);
+ track_mouse = FALSE;
+ }
+ }
+}
+
+void _toggle_trackfocus(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data)
+{
+ if (checkmenuitem->active)
+ {
+ track_focus = TRUE;
+ focus_tracker_id = atk_add_focus_tracker (_print_accessible);
+ }
+ else
+ {
+ g_print ("No longer tracking focus.\n");
+ track_focus = FALSE;
+ atk_remove_focus_tracker (focus_tracker_id);
+ }
+}
--- /dev/null
+#include <string.h>
+#include <stdlib.h>
+#include <gtk/gtk.h>
+#include "testlib.h"
+
+/*
+ * This module is used to test the implementation of AtkAction,
+ * i.e. the getting of the name and the getting and setting of description
+ */
+
+static void _create_event_watcher (void);
+static void _check_object (AtkObject *obj);
+
+static void
+_check_object (AtkObject *obj)
+{
+ G_CONST_RETURN char *accessible_name;
+ G_CONST_RETURN gchar * typename = NULL;
+
+ if (GTK_IS_ACCESSIBLE (obj))
+ {
+ GtkWidget* widget = NULL;
+
+ widget = GTK_ACCESSIBLE (obj)->widget;
+ typename = g_type_name (GTK_OBJECT_TYPE (widget));
+ g_print ("Widget type name: %s\n", typename ? typename : "NULL");
+ }
+ typename = g_type_name (G_OBJECT_TYPE (obj));
+ g_print ("Accessible type name: %s\n", typename ? typename : "NULL");
+ accessible_name = atk_object_get_name (obj);
+ if (accessible_name)
+ g_print ("Name: %s\n", accessible_name);
+
+ if (ATK_IS_ACTION (obj))
+ {
+ AtkAction *action = ATK_ACTION (obj);
+ gint n_actions, i;
+ G_CONST_RETURN gchar *action_name;
+ G_CONST_RETURN gchar *action_desc;
+ G_CONST_RETURN gchar *action_binding;
+ const gchar *desc = "Test description";
+
+ n_actions = atk_action_get_n_actions (action);
+ g_print ("AtkAction supported number of actions: %d\n", n_actions);
+ for (i = 0; i < n_actions; i++)
+ {
+ action_name = atk_action_get_name (action, i);
+ g_print ("Name of Action %d: %s\n", i, action_name);
+ action_binding = atk_action_get_keybinding (action, i);
+ if (action_binding)
+ g_print ("Name of Action Keybinding %d: %s\n", i, action_binding);
+
+ if (!atk_action_set_description (action, i, desc))
+ {
+ g_print ("atk_action_set_description failed\n");
+ }
+ else
+ {
+ action_desc = atk_action_get_description (action, i);
+ if (strcmp (desc, action_desc) != 0)
+ {
+ g_print ("Problem with setting and getting action description\n");
+ }
+ }
+ }
+ if (atk_action_set_description (action, n_actions, desc))
+ {
+ g_print ("atk_action_set_description succeeded but should not have\n");
+ }
+ }
+}
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_check_object);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testaction Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <gtk/gtk.h>
+#include "testlib.h"
+
+/*
+ * This module is used to test the accessible implementation for buttons
+ *
+ * 1) It verifies that ATK_STATE_ARMED is set when a button is pressed
+ * To check this click on the button whose name is specified in the
+ * environment variable TEST_ACCESSIBLE_NAME or "button box" if the
+ * environment variable is not set.
+ *
+ * 2) If the environment variable TEST_ACCESSIBLE_AUTO is set the program
+ * will execute the action defined for a GailButton once.
+ *
+ * 3) Change an inconsistent toggle button to be consistent and vice versa.
+ *
+ * Note that currently this code needs to be changed manually to test
+ * different actions.
+ */
+
+static void _create_event_watcher (void);
+static void _check_object (AtkObject *obj);
+static void button_pressed_handler (GtkButton *button);
+static void _print_states (AtkObject *obj);
+static void _print_button_image_info(AtkObject *obj);
+static gint _do_button_action (gpointer data);
+static gint _toggle_inconsistent (gpointer data);
+static gint _finish_button_action (gpointer data);
+
+#define NUM_VALID_ROLES 4
+
+static void
+_check_object (AtkObject *obj)
+{
+ AtkRole role;
+ static gboolean first_time = TRUE;
+
+ role = atk_object_get_role (obj);
+ if (role == ATK_ROLE_FRAME)
+ /*
+ * Find the specified button in the window
+ */
+ {
+ AtkRole valid_roles[NUM_VALID_ROLES];
+ G_CONST_RETURN char *name;
+ AtkObject *atk_button;
+ GtkWidget *widget;
+
+ valid_roles[0] = ATK_ROLE_PUSH_BUTTON;
+ valid_roles[1] = ATK_ROLE_TOGGLE_BUTTON;
+ valid_roles[2] = ATK_ROLE_CHECK_BOX;
+ valid_roles[3] = ATK_ROLE_RADIO_BUTTON;
+
+ name = g_getenv ("TEST_ACCESSIBLE_NAME");
+ if (name == NULL)
+ name = "button box";
+ atk_button = find_object_by_accessible_name_and_role (obj, name,
+ valid_roles, NUM_VALID_ROLES);
+
+ if (atk_button == NULL)
+ {
+ g_print ("Object not found for %s\n", name);
+ return;
+ }
+ g_assert (GTK_IS_ACCESSIBLE (atk_button));
+ widget = GTK_ACCESSIBLE (atk_button)->widget;
+ g_assert (GTK_IS_BUTTON (widget));
+ g_signal_connect (GTK_OBJECT (widget),
+ "pressed",
+ GTK_SIGNAL_FUNC (button_pressed_handler),
+ NULL);
+ if (GTK_IS_TOGGLE_BUTTON (widget))
+ {
+ _toggle_inconsistent (GTK_TOGGLE_BUTTON (widget));
+ }
+ if (first_time)
+ first_time = FALSE;
+ else
+ return;
+
+ if (g_getenv ("TEST_ACCESSIBLE_AUTO"))
+ {
+ gtk_idle_add (_do_button_action, atk_button);
+ }
+ }
+}
+
+static gint _toggle_inconsistent (gpointer data)
+{
+ GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (data);
+
+ if (gtk_toggle_button_get_inconsistent (toggle_button))
+ {
+ gtk_toggle_button_set_inconsistent (toggle_button, FALSE);
+ }
+ else
+ {
+ gtk_toggle_button_set_inconsistent (toggle_button, TRUE);
+ }
+ return FALSE;
+}
+
+static gint _do_button_action (gpointer data)
+{
+ AtkObject *obj = ATK_OBJECT (data);
+
+ atk_action_do_action (ATK_ACTION (obj), 2);
+
+ gtk_timeout_add (5000, _finish_button_action, obj);
+ return FALSE;
+}
+
+static gint _finish_button_action (gpointer data)
+{
+#if 0
+ AtkObject *obj = ATK_OBJECT (data);
+
+ atk_action_do_action (ATK_ACTION (obj), 0);
+#endif
+
+ return FALSE;
+}
+
+static void
+button_pressed_handler (GtkButton *button)
+{
+ AtkObject *obj;
+
+ obj = gtk_widget_get_accessible (GTK_WIDGET (button));
+ _print_states (obj);
+ _print_button_image_info (obj);
+
+ if (GTK_IS_TOGGLE_BUTTON (button))
+ {
+ gtk_idle_add (_toggle_inconsistent, GTK_TOGGLE_BUTTON (button));
+ }
+}
+
+static void
+_print_states (AtkObject *obj)
+{
+ AtkStateSet *state_set;
+ gint i;
+
+ state_set = atk_object_ref_state_set (obj);
+
+ g_print ("*** Start states ***\n");
+ for (i = 0; i < 64; i++)
+ {
+ AtkStateType one_state;
+ G_CONST_RETURN gchar *name;
+
+ if (atk_state_set_contains_state (state_set, i))
+ {
+ one_state = i;
+
+ name = atk_state_type_get_name (one_state);
+
+ if (name)
+ g_print("%s\n", name);
+ }
+ }
+ g_object_unref (state_set);
+ g_print ("*** End states ***\n");
+}
+
+static void
+_print_button_image_info(AtkObject *obj) {
+
+ gint height, width;
+ G_CONST_RETURN gchar *desc;
+
+ height = width = 0;
+
+ if(!ATK_IS_IMAGE(obj))
+ return;
+
+ g_print("*** Start Button Image Info ***\n");
+ desc = atk_image_get_image_description(ATK_IMAGE(obj));
+ g_print ("atk_image_get_image_desc returns : %s\n", desc ? desc : "<NULL>");
+ atk_image_get_image_size(ATK_IMAGE(obj), &height ,&width);
+ g_print("atk_image_get_image_size returns: height %d width %d\n",height,width);
+ if(atk_image_set_image_description(ATK_IMAGE(obj), "New image Description")){
+ desc = atk_image_get_image_description(ATK_IMAGE(obj));
+ g_print ("atk_image_get_image_desc now returns : %s\n",desc ?desc:"<NULL>");
+ }
+ g_print("*** End Button Image Info ***\n");
+
+
+}
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_check_object);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testbutton Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <gtk/gtk.h>
+#include <testlib.h>
+
+static void _test_selection (AtkObject *obj);
+static void _check_combo_box (AtkObject *obj);
+static void _check_children (AtkObject *obj);
+static gint _open_combo_list (gpointer data);
+static gint _close_combo_list (gpointer data);
+
+#define NUM_VALID_ROLES 1
+
+static void _check_children (AtkObject *obj)
+{
+ gint n_children, i, j;
+ AtkObject *child;
+ AtkObject *grand_child;
+ AtkObject *parent;
+
+ n_children = atk_object_get_n_accessible_children (obj);
+
+ if (n_children > 1)
+ {
+ g_print ("*** Unexpected number of children for combo box: %d\n",
+ n_children);
+ return;
+ }
+ if (n_children == 2)
+ {
+ child = atk_object_ref_accessible_child (obj, 1);
+ g_return_if_fail (atk_object_get_role (child) == ATK_ROLE_TEXT);
+ parent = atk_object_get_parent (child);
+ j = atk_object_get_index_in_parent (child);
+ if (j != 1)
+ g_print ("*** inconsistency between parent and children %d %d ***\n",
+ 1, j);
+ g_object_unref (G_OBJECT (child));
+ }
+
+ child = atk_object_ref_accessible_child (obj, 0);
+ g_return_if_fail (atk_object_get_role (child) == ATK_ROLE_LIST);
+ parent = atk_object_get_parent (child);
+ j = atk_object_get_index_in_parent (child);
+ if (j != 0)
+ g_print ("*** inconsistency between parent and children %d %d ***\n",
+ 0, j);
+
+ n_children = atk_object_get_n_accessible_children (child);
+ for (i = 0; i < n_children; i++)
+ {
+ G_CONST_RETURN gchar *name;
+
+ grand_child = atk_object_ref_accessible_child (child, i);
+ name = atk_object_get_name (grand_child);
+ g_print ("Index: %d Name: %s\n", i, name ? name : "<NULL>");
+ g_object_unref (G_OBJECT (grand_child));
+ }
+ g_object_unref (G_OBJECT (child));
+}
+
+static void _test_selection (AtkObject *obj)
+{
+ gint count;
+ gint n_children;
+ AtkObject *list;
+
+ count = atk_selection_get_selection_count (ATK_SELECTION (obj));
+ g_return_if_fail (count == 0);
+
+ list = atk_object_ref_accessible_child (obj, 0);
+ n_children = atk_object_get_n_accessible_children (list);
+ g_object_unref (G_OBJECT (list));
+
+ atk_selection_add_selection (ATK_SELECTION (obj), n_children - 1);
+ count = atk_selection_get_selection_count (ATK_SELECTION (obj));
+ g_return_if_fail (count == 1);
+ g_return_if_fail (atk_selection_is_child_selected (ATK_SELECTION (obj),
+ n_children - 1));
+ atk_selection_add_selection (ATK_SELECTION (obj), 0);
+ count = atk_selection_get_selection_count (ATK_SELECTION (obj));
+ g_return_if_fail (count == 1);
+ g_return_if_fail (atk_selection_is_child_selected (ATK_SELECTION (obj), 0));
+ atk_selection_clear_selection (ATK_SELECTION (obj));
+ count = atk_selection_get_selection_count (ATK_SELECTION (obj));
+ g_return_if_fail (count == 0);
+}
+
+static void _check_combo_box (AtkObject *obj)
+{
+ static gboolean done = FALSE;
+ static gboolean done_selection = FALSE;
+ AtkRole role;
+
+ role = atk_object_get_role (obj);
+
+ if (role == ATK_ROLE_FRAME)
+ {
+ AtkRole roles[NUM_VALID_ROLES];
+ AtkObject *combo_obj;
+
+ if (done_selection)
+ return;
+
+ roles[0] = ATK_ROLE_COMBO_BOX;
+
+ combo_obj = find_object_by_role (obj, roles, NUM_VALID_ROLES);
+
+ if (combo_obj)
+ {
+ if (!done_selection)
+ {
+ done_selection = TRUE;
+ }
+ if (g_getenv ("TEST_ACCESSIBLE_COMBO_NOEDIT") != NULL)
+ {
+ GtkEntry *entry;
+
+ entry = GTK_ENTRY (GTK_COMBO (GTK_ACCESSIBLE (combo_obj)->widget)->entry);
+ gtk_entry_set_editable (entry, FALSE);
+ }
+ _check_children (combo_obj);
+ _test_selection (combo_obj);
+ }
+
+ return;
+ }
+ if (role != ATK_ROLE_COMBO_BOX)
+ return;
+
+ g_print ("*** Start ComboBox ***\n");
+ _check_children (obj);
+
+ if (!done)
+ {
+ gtk_idle_add (_open_combo_list, obj);
+ done = TRUE;
+ }
+ else
+ return;
+ g_print ("*** End ComboBox ***\n");
+}
+
+static gint _open_combo_list (gpointer data)
+{
+ AtkObject *obj = ATK_OBJECT (data);
+
+ g_print ("_open_combo_list\n");
+ atk_action_do_action (ATK_ACTION (obj), 0);
+
+ gtk_timeout_add (5000, _close_combo_list, obj);
+ return FALSE;
+}
+
+static gint _close_combo_list (gpointer data)
+{
+ AtkObject *obj = ATK_OBJECT (data);
+
+ gint count;
+ gint n_children;
+ AtkObject *list;
+
+ count = atk_selection_get_selection_count (ATK_SELECTION (obj));
+ g_return_val_if_fail (count == 0, FALSE);
+
+ list = atk_object_ref_accessible_child (obj, 0);
+ n_children = atk_object_get_n_accessible_children (list);
+ g_object_unref (G_OBJECT (list));
+
+ atk_selection_add_selection (ATK_SELECTION (obj), n_children - 1);
+
+ atk_action_do_action (ATK_ACTION (obj), 0);
+
+ return FALSE;
+}
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_check_combo_box);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testcombo Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <atk/atk.h>
+
+static void _check_position (AtkObject *obj);
+
+static void _check_position (AtkObject *obj)
+{
+ AtkObject *parent, *ret_object;
+
+ gint x, y, width, height;
+ gint x1, y1, width1, height1;
+
+ x = y = width = height = 0;
+ x1 = y1 = width1 = height1 = 0;
+
+ if (!ATK_IS_COMPONENT (obj))
+ return;
+
+ atk_component_get_extents (ATK_COMPONENT(obj), &x, &y, &width, &height, ATK_XY_SCREEN);
+ atk_component_get_position (ATK_COMPONENT(obj), &x1, &y1, ATK_XY_SCREEN );
+ atk_component_get_size (ATK_COMPONENT(obj), &width1, &height1);
+ if ((x1 != x) || (y1 != y))
+ {
+ g_print ("atk_component_get_extents and atk_get_position give different"
+ " values: %d,%d %d,%d\n", x, y, x1, y1);
+ }
+ if ((width1 != width) || (height1 != height))
+ {
+ g_print ("atk_component_get_extents and atk_get_size give different"
+ " values: %d,%d %d,%d\n", width, height, width1, height1);
+ }
+
+ atk_component_get_position (ATK_COMPONENT(obj), &x1, &y1, ATK_XY_SCREEN);
+ g_print ("Object Type: %s\n", g_type_name (G_OBJECT_TYPE (obj)));
+ g_print ("Object at %d, %d on screen\n", x1, y1);
+ g_print ("Object at %d, %d, size: %d, %d\n", x, y, width, height);
+
+ parent = atk_object_get_parent (obj);
+
+ if (ATK_IS_COMPONENT (parent))
+ {
+ gint px, py, pwidth, pheight;
+
+ atk_component_get_extents (ATK_COMPONENT(parent),
+ &px, &py, &pwidth, &pheight, ATK_XY_SCREEN);
+ g_print ("Parent Type: %s\n", g_type_name (G_OBJECT_TYPE (parent)));
+ g_print ("Parent at %d, %d, size: %d, %d\n", px, py, pwidth, pheight);
+ ret_object = atk_component_ref_accessible_at_point (ATK_COMPONENT (parent),
+ x, y, ATK_XY_SCREEN);
+
+ if (!ret_object)
+ {
+ g_print ("1:atk_component_ref_accessible_at_point returns NULL\n");
+ }
+ else if (ret_object != obj)
+ {
+ g_print ("1:atk_component_ref_accessible_at_point returns wrong value for %d %d\n",
+ x, y);
+ atk_component_get_extents (ATK_COMPONENT(ret_object),
+ &px, &py, &pwidth, &pheight, ATK_XY_SCREEN);
+ g_print ("ret_object at %d, %d, size: %d, %d\n", px, py, pwidth, pheight);
+ }
+ if (ret_object)
+ g_object_unref (G_OBJECT (ret_object));
+ ret_object = atk_component_ref_accessible_at_point (ATK_COMPONENT (parent),
+ x+width-1, y+height-1, ATK_XY_SCREEN);
+ if (!ret_object)
+ {
+ g_print ("2:atk_component_ref_accessible_at_point returns NULL\n");
+ }
+ else if (ret_object != obj)
+ {
+ g_print ("2:atk_component_ref_accessible_at_point returns wrong value for %d %d\n",
+ x+width-1, y+height-1);
+ }
+ if (ret_object)
+ g_object_unref (G_OBJECT (ret_object));
+ ret_object = atk_component_ref_accessible_at_point (ATK_COMPONENT (parent),
+ x-1, y-1, ATK_XY_SCREEN);
+ if ((ret_object) && (ret_object == obj))
+ {
+ g_print ("3:atk_component_ref_accessible_at_point returns wrong value for %d %d\n",
+ x-1, y-1);
+ }
+ if (ret_object)
+ g_object_unref (G_OBJECT (ret_object));
+ ret_object = atk_component_ref_accessible_at_point (ATK_COMPONENT (parent),
+ x+width, y+height, ATK_XY_SCREEN);
+ if ((ret_object) && (ret_object == obj))
+ {
+ g_print ("4:atk_component_ref_accessible_at_point returns wrong value for %d %d\n",
+ x+width, y+height);
+ }
+ if (ret_object)
+ g_object_unref (G_OBJECT (ret_object));
+ }
+ if (!atk_component_contains (ATK_COMPONENT(obj), x, y, ATK_XY_SCREEN))
+ g_print ("Component does not contain position, %d %d\n", x, y);
+ if (atk_component_contains (ATK_COMPONENT(obj), x-1, y-1, ATK_XY_SCREEN))
+ g_print ("Component does contain position, %d %d\n", x-1, y-1);
+ if (!atk_component_contains (ATK_COMPONENT(obj), x+width-1, y+height-1, ATK_XY_SCREEN))
+ g_print ("Component does not contain position, %d %d\n",
+ x+width-1, y+height-1);
+ if (atk_component_contains (ATK_COMPONENT(obj), x+width, y+height, ATK_XY_SCREEN))
+ g_print ("Component does contain position, %d %d\n", x+width, y+height);
+}
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_check_position);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testcomponent Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <gtk/gtk.h>
+#include "testlib.h"
+#include <stdlib.h>
+
+/*
+ * This test modules tests the AtkImage interface. When the module is loaded
+ * with testgtk , it also creates a dialog that contains GtkArrows and a
+ * GtkImage.
+ *
+ */
+
+typedef struct
+{
+ GtkWidget *dialog;
+ GtkWidget *arrow1;
+ GtkWidget *arrow2;
+ GtkWidget *arrow3;
+ GtkWidget *arrow4;
+ GtkWidget *close_button;
+ GtkImage *image;
+}MainDialog;
+
+static void destroy (GtkWidget *widget, gpointer data)
+{
+ gtk_widget_destroy(GTK_WIDGET(data));
+}
+
+static void _check_arrows (AtkObject *obj)
+{
+ AtkRole role;
+ MainDialog *md;
+ static gint visibleDialog = 0;
+
+
+ role = atk_object_get_role(obj);
+ if(role == ATK_ROLE_FRAME) {
+
+ md = (MainDialog *) malloc (sizeof(MainDialog));
+ if (visibleDialog == 0)
+ {
+ md->arrow1 = gtk_arrow_new(GTK_ARROW_UP,GTK_SHADOW_IN);
+ md->arrow2 = gtk_arrow_new(GTK_ARROW_DOWN,GTK_SHADOW_IN);
+ md->arrow3 = gtk_arrow_new(GTK_ARROW_LEFT,GTK_SHADOW_OUT);
+ md->arrow4 = gtk_arrow_new(GTK_ARROW_RIGHT,GTK_SHADOW_OUT);
+ md->dialog = gtk_dialog_new();
+ gtk_window_set_modal(GTK_WINDOW(md->dialog), TRUE);
+ gtk_box_pack_start(GTK_BOX (GTK_DIALOG (md->dialog)->vbox),
+ md->arrow1, TRUE,TRUE, 0);
+ gtk_box_pack_start(GTK_BOX (GTK_DIALOG (md->dialog)->vbox),
+ md->arrow2, TRUE,TRUE, 0);
+ gtk_box_pack_start(GTK_BOX (GTK_DIALOG (md->dialog)->vbox),
+ md->arrow3, TRUE,TRUE, 0);
+ gtk_box_pack_start(GTK_BOX (GTK_DIALOG (md->dialog)->vbox),
+ md->arrow4, TRUE,TRUE, 0);
+ g_signal_connect(GTK_OBJECT(md->dialog), "destroy",
+ GTK_SIGNAL_FUNC(destroy), md->dialog);
+
+ md->image = GTK_IMAGE(gtk_image_new_from_file("circles.xbm"));
+ gtk_box_pack_start(GTK_BOX (GTK_DIALOG (md->dialog)->vbox),
+ GTK_WIDGET(md->image), TRUE,TRUE, 0);
+ md->close_button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
+ g_signal_connect(GTK_OBJECT(md->close_button), "clicked",
+ GTK_SIGNAL_FUNC(destroy), md->dialog);
+
+ gtk_box_pack_start(GTK_BOX (GTK_DIALOG (md->dialog)->action_area),
+ md->close_button, TRUE,TRUE, 0);
+
+
+ gtk_widget_show_all(md->dialog);
+ visibleDialog = 1;
+
+
+ }
+ }
+}
+
+
+static void
+_print_image_info(AtkObject *obj) {
+
+ gint height, width;
+ G_CONST_RETURN gchar *desc;
+ G_CONST_RETURN gchar *name = atk_object_get_name (obj);
+ G_CONST_RETURN gchar *type_name = g_type_name(G_TYPE_FROM_INSTANCE (obj));
+
+ height = width = 0;
+
+
+ if(!ATK_IS_IMAGE(obj))
+ return;
+
+ g_print("atk_object_get_name : %s\n", name ? name : "<NULL>");
+ g_print("atk_object_get_type_name : %s\n",type_name ?type_name :"<NULL>");
+ g_print("*** Start Image Info ***\n");
+ desc = atk_image_get_image_description(ATK_IMAGE(obj));
+ g_print ("atk_image_get_image_desc returns : %s\n",desc ? desc:"<NULL>");
+ atk_image_get_image_size(ATK_IMAGE(obj), &height ,&width);
+ g_print("atk_image_get_image_size returns: height %d width %d\n",
+ height,width);
+ if(atk_image_set_image_description(ATK_IMAGE(obj),"New image Description")){
+ desc = atk_image_get_image_description(ATK_IMAGE(obj));
+ g_print ("atk_image_get_image_desc now returns : %s\n",desc?desc:"<NULL>");
+ }
+ g_print("*** End Image Info ***\n");
+
+
+}
+static void _traverse_children (AtkObject *obj)
+{
+ gint n_children, i;
+
+ n_children = atk_object_get_n_accessible_children (obj);
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject *child;
+
+ child = atk_object_ref_accessible_child (obj, i);
+ _print_image_info(child);
+ _traverse_children (child);
+ g_object_unref (G_OBJECT (child));
+ }
+}
+
+
+static void _check_objects (AtkObject *obj)
+{
+ AtkRole role;
+
+ g_print ("Start of _check_values\n");
+
+ _check_arrows(obj);
+ role = atk_object_get_role (obj);
+
+ if (role == ATK_ROLE_FRAME || role == ATK_ROLE_DIALOG)
+ {
+ /*
+ * Add handlers to all children.
+ */
+ _traverse_children (obj);
+ }
+ g_print ("End of _check_values\n");
+}
+
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_check_objects);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testimages Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "testlib.h"
+
+static gint _get_position_in_array (gint window,
+ gchar *the_test_name);
+static gint _get_position_in_parameters (gint window,
+ gchar *label,
+ gint position);
+static void _create_output_window (OutputWindow **outwin);
+static gboolean _create_select_tests_window (AtkObject *obj,
+ TLruntest runtest,
+ OutputWindow **outwin);
+static void _toggle_selectedcb (GtkWidget *widget,
+ gpointer test);
+static void _testselectioncb (GtkWidget *widget,
+ gpointer data);
+static void _destroy (GtkWidget *widget,
+ gpointer data);
+
+/* General functions */
+
+/**
+ * find_object_by_role:
+ * @obj: An #AtkObject
+ * @roles: An array of roles to search for
+ * @num_roles: The number of entries in @roles
+ *
+ * Find the #AtkObject which is a decendant of the specified @obj
+ * which is of an #AtkRole type specified in the @roles array.
+ *
+ * Returns: the #AtkObject that meets the specified criteria or NULL
+ * if no object is found.
+ **/
+AtkObject*
+find_object_by_role (AtkObject *obj,
+ AtkRole *roles,
+ gint num_roles)
+{
+ /*
+ * Find the first object which is a descendant of the specified object
+ * which matches the specified role.
+ *
+ * This function returns a reference to the AtkObject which should be
+ * removed when finished with the object.
+ */
+ gint i, j;
+ gint n_children;
+ AtkObject *child;
+
+ if (obj == NULL)
+ return NULL;
+
+ for (j=0; j < num_roles; j++)
+ {
+ if (atk_object_get_role (obj) == roles[j])
+ return obj;
+ }
+
+ n_children = atk_object_get_n_accessible_children (obj);
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject* found_obj;
+
+ child = atk_object_ref_accessible_child (obj, i);
+
+ if (child == NULL)
+ continue;
+
+ for (j=0; j < num_roles; j++)
+ {
+ if (atk_object_get_role (child) == roles[j])
+ return child;
+ }
+
+ found_obj = find_object_by_role (child, roles, num_roles);
+ g_object_unref (child);
+ if (found_obj)
+ return found_obj;
+ }
+ return NULL;
+}
+
+/**
+ * find_object_by_name_and_role:
+ * @obj: An #AtkObject
+ * @name: The GTK widget name
+ * @roles: An array of roles to search for
+ * @num_roles: The number of entries in @roles
+ *
+ * Find the #AtkObject which is a decendant of the specified @obj
+ * which is of an #AtkRole type specified in the @roles array which
+ * also has the GTK widget name specified in @name.
+ *
+ * Returns: the #AtkObject that meets the specified criteria or NULL
+ * if no object is found.
+ **/
+AtkObject*
+find_object_by_name_and_role(AtkObject *obj,
+ const gchar *name,
+ AtkRole *roles,
+ gint num_roles)
+{
+ AtkObject *child;
+ GtkWidget* widget;
+ gint i, j;
+ gint n_children;
+
+ if (obj == NULL)
+ return NULL;
+
+ widget = GTK_ACCESSIBLE (obj)->widget;
+ if (GTK_IS_WIDGET (widget))
+ {
+ if (strcmp (name, gtk_widget_get_name(GTK_WIDGET (widget))) == 0)
+ {
+ for (j=0; j < num_roles; j++)
+ {
+ if (atk_object_get_role (obj) == roles[j])
+ return obj;
+ }
+ }
+ }
+
+ n_children = atk_object_get_n_accessible_children (obj);
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject* found_obj;
+
+ child = atk_object_ref_accessible_child (obj, i);
+
+ if (child == NULL)
+ continue;
+
+ widget = GTK_ACCESSIBLE (child)->widget;
+ if (GTK_IS_WIDGET (widget))
+ {
+ if (strcmp(name, gtk_widget_get_name(GTK_WIDGET (widget))) == 0)
+ {
+ for (j=0; j < num_roles; j++)
+ {
+ if (atk_object_get_role (child) == roles[j])
+ return child;
+ }
+ }
+ }
+ found_obj = find_object_by_name_and_role (child, name, roles, num_roles);
+ g_object_unref (child);
+ if (found_obj)
+ return found_obj;
+ }
+ return NULL;
+}
+
+/**
+ * find_object_by_accessible_name_and_role:
+ * @obj: An #AtkObject
+ * @name: The accessible name
+ * @roles: An array of roles to search for
+ * @num_roles: The number of entries in @roles
+ *
+ * Find the #AtkObject which is a decendant of the specified @obj
+ * which has the specified @name and matches one of the
+ * specified @roles.
+ *
+ * Returns: the #AtkObject that meets the specified criteria or NULL
+ * if no object is found.
+ */
+AtkObject*
+find_object_by_accessible_name_and_role (AtkObject *obj,
+ const gchar *name,
+ AtkRole *roles,
+ gint num_roles)
+{
+ AtkObject *child;
+ gint i, j;
+ gint n_children;
+ G_CONST_RETURN gchar *accessible_name;
+
+ if (obj == NULL)
+ return NULL;
+
+ accessible_name = atk_object_get_name (obj);
+ if (accessible_name && (strcmp(name, accessible_name) == 0))
+ {
+ for (j=0; j < num_roles; j++)
+ {
+ if (atk_object_get_role (obj) == roles[j])
+ return obj;
+ }
+ }
+
+ n_children = atk_object_get_n_accessible_children (obj);
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject* found_obj;
+
+ child = atk_object_ref_accessible_child (obj, i);
+
+ if (child == NULL)
+ continue;
+
+ accessible_name = atk_object_get_name (child);
+ if (accessible_name && (strcmp(name, accessible_name) == 0))
+ {
+ for (j=0; j < num_roles; j++)
+ {
+ if (atk_object_get_role (child) == roles[j])
+ return child;
+ }
+ }
+ found_obj = find_object_by_accessible_name_and_role (child, name,
+ roles, num_roles);
+ g_object_unref (child);
+ if (found_obj)
+ return found_obj;
+ }
+ return NULL;
+}
+
+/**
+ * find_object_by_name_and_role:
+ * @obj: An #AtkObject
+ * @type: The type
+ *
+ * Find the #AtkObject which is a decendant of the specified @obj
+ * which has the specified @type.
+ *
+ * Returns: the #AtkObject that meets the specified criteria or NULL
+ * if no object is found.
+ */
+AtkObject*
+find_object_by_type (AtkObject *obj,
+ gchar *type)
+{
+ /*
+ * Find the first object which is a descendant of the specified object
+ * which matches the specified type.
+ *
+ * This function returns a reference to the AtkObject which should be
+ * removed when finished with the object.
+ */
+ gint i;
+ gint n_children;
+ AtkObject *child;
+ G_CONST_RETURN gchar * typename = NULL;
+
+ if (obj == NULL)
+ return NULL;
+
+ typename = g_type_name (G_OBJECT_TYPE (obj));
+ if (strcmp (typename, type) == 0)
+ return obj;
+
+ n_children = atk_object_get_n_accessible_children (obj);
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject* found_obj;
+
+ child = atk_object_ref_accessible_child (obj, i);
+
+ if (child == NULL)
+ continue;
+
+ typename = g_type_name (G_OBJECT_TYPE (child));
+
+ if (strcmp (typename, type) == 0)
+ return child;
+
+ found_obj = find_object_by_type (child, type);
+ g_object_unref (child);
+ if (found_obj)
+ return found_obj;
+ }
+ return NULL;
+}
+
+/**
+ * already_accessed_atk_object
+ * @obj: An #AtkObject
+ *
+ * Keeps a static GPtrArray of objects that have been passed into this
+ * function.
+ *
+ * Returns: TRUE if @obj has been passed into this function before
+ * and FALSE otherwise.
+ */
+gboolean
+already_accessed_atk_object (AtkObject *obj)
+{
+ static GPtrArray *obj_array = NULL;
+ gboolean found = FALSE;
+ gint i;
+
+ /*
+ * We create a property handler for each object if one was not associated
+ * with it already.
+ *
+ * We add it to our array of objects which have property handlers; if an
+ * object is destroyed it remains in the array.
+ */
+ if (obj_array == NULL)
+ obj_array = g_ptr_array_new ();
+
+ for (i = 0; i < obj_array->len; i++)
+ {
+ if (obj == g_ptr_array_index (obj_array, i))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found)
+ g_ptr_array_add (obj_array, obj);
+
+ return found;
+}
+
+/**
+ * display_children
+ * @obj: An #AtkObject
+ * @depth: Number of spaces to indent output.
+ * @child_number: The child number of this object.
+ *
+ * Displays the hierarchy of widgets starting from @obj.
+ **/
+void
+display_children (AtkObject *obj,
+ gint depth,
+ gint child_number)
+{
+ display_children_to_depth(obj, -1, depth, child_number);
+}
+
+/**
+ * display_children_to_depth
+ * @obj: An #AtkObject
+ * @to_depth: Display to this depth.
+ * @depth: Number of spaces to indent output.
+ * @child_number: The child number of this object.
+ *
+ * Displays the hierarchy of widgets starting from @obj only
+ * to the specified depth.
+ **/
+void
+display_children_to_depth (AtkObject *obj,
+ gint to_depth,
+ gint depth,
+ gint child_number)
+{
+ AtkRole role;
+ const gchar *rolename;
+ const gchar *typename;
+ gint n_children, parent_index, i;
+
+ if (to_depth >= 0 && depth > to_depth)
+ return;
+
+ if (obj == NULL)
+ return;
+
+ for (i=0; i < depth; i++)
+ g_print(" ");
+
+ role = atk_object_get_role (obj);
+ rolename = atk_role_get_name (role);
+
+ /*
+ * Note that child_number and parent_index should be the same
+ * unless there is an error.
+ */
+ parent_index = atk_object_get_index_in_parent(obj);
+ g_print("child <%d == %d> ", child_number, parent_index);
+
+ n_children = atk_object_get_n_accessible_children (obj);
+ g_print ("children <%d> ", n_children);
+
+ if (rolename)
+ g_print("role <%s>, ", rolename);
+ else
+ g_print("role <error>");
+
+ if (GTK_IS_ACCESSIBLE(obj))
+ {
+ GtkWidget *widget;
+
+ widget = GTK_ACCESSIBLE (obj)->widget;
+ g_print("name <%s>, ", gtk_widget_get_name(GTK_WIDGET (widget)));
+ }
+ else
+ g_print("name <NULL>, ");
+
+ typename = g_type_name (G_OBJECT_TYPE (obj));
+ g_print ("typename <%s>\n", typename);
+
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject *child;
+
+ child = atk_object_ref_accessible_child (obj, i);
+ if (child != NULL)
+ {
+ display_children_to_depth (child, to_depth, depth + 1, i);
+ g_object_unref (G_OBJECT (child));
+ }
+ }
+}
+
+/* Test GUI logic */
+
+/* GUI Information for the Select Tests Window */
+typedef struct
+{
+ GtkWidget *selecttestsWindow;
+ GtkWidget *hbox;
+ GtkWidget *vbox;
+ GtkWidget *label;
+ GtkWidget *textInsert;
+ GtkWidget *button;
+ gchar *selecttestsTitle;
+}MainDialog;
+
+/* Functionality information about each added test */
+typedef struct
+{
+ GtkWidget *toggleButton;
+ GtkWidget *hbox;
+ GtkWidget *parameterLabel[MAX_PARAMS];
+ GtkWidget *parameterInput[MAX_PARAMS];
+ gchar *testName;
+ gint numParameters;
+}TestList;
+
+typedef struct
+{
+ TLruntest runtest;
+ AtkObject* obj;
+ gint win_num;
+}TestCB;
+
+static MainDialog *md[MAX_WINDOWS];
+static OutputWindow *ow;
+
+/* An array containing function information on all of the tests */
+static TestList listoftests[MAX_WINDOWS][MAX_TESTS];
+
+/* A counter for the actual number of added tests */
+gint counter;
+
+/* A global for keeping track of the window numbers */
+static gint window_no = 0;
+/* An array containing the names of the tests that are "on" */
+static gchar *onTests[MAX_WINDOWS][MAX_TESTS];
+static gint g_visibleDialog = 0;
+static gint testcount[MAX_WINDOWS];
+static TestCB testcb[MAX_WINDOWS];
+
+/**
+ * create_windows:
+ * @obj: An #AtkObject
+ * @runtest: The callback function to run when the "Run Tests" button
+ * is clicked.
+ * @outwin: The output window to use. If NULL is passed in, then
+ * create a new one.
+ *
+ * Creates the test window and the output window (if @outwin is NULL)
+ * Runs _create_output_window() and _create_select_tests_window()
+ * and sets g_visibleDialog to 1
+ *
+ * Returns: The window number of the created window if successful, -1 otherwise.
+ **/
+gint
+create_windows (AtkObject *obj,
+ TLruntest runtest,
+ OutputWindow **outwin)
+{
+ gboolean valid;
+ gint tmp;
+
+ g_visibleDialog = 1;
+ _create_output_window(outwin);
+ valid = _create_select_tests_window(obj, runtest, outwin);
+ if (valid)
+ {
+ tmp = window_no;
+ window_no++;
+ return tmp;
+ }
+ else
+ return -1;
+}
+
+/**
+ * _create_output_window
+ * @outwin: If outwin is passed in as NULL, a new output window is created
+ * otherwise, the outwin passed in is shared.
+ *
+ * Creates the Test Result Output Window .
+ **/
+static void
+_create_output_window (OutputWindow **outwin)
+{
+ GtkWidget *view;
+ GtkWidget *scrolled_window;
+ OutputWindow *localow;
+
+ if (*outwin == NULL)
+ {
+ localow = (OutputWindow *) malloc (sizeof(OutputWindow));
+
+ localow->outputBuffer = gtk_text_buffer_new(NULL);
+ view = gtk_text_view_new_with_buffer(GTK_TEXT_BUFFER(localow->outputBuffer));
+ gtk_widget_set_usize(view, 700, 500);
+ gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(view), GTK_WRAP_WORD);
+ gtk_text_view_set_editable(GTK_TEXT_VIEW(view), FALSE);
+
+ localow->outputWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title(GTK_WINDOW(localow->outputWindow), "Test Output");
+ scrolled_window = gtk_scrolled_window_new(NULL, NULL);
+
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_container_add(GTK_CONTAINER(localow->outputWindow), scrolled_window);
+ gtk_container_add(GTK_CONTAINER(scrolled_window), view);
+ gtk_text_buffer_get_iter_at_offset(localow->outputBuffer, &localow->outputIter, 0);
+ gtk_widget_show(view);
+ gtk_widget_show(scrolled_window);
+ gtk_widget_show(localow->outputWindow);
+
+ gtk_text_buffer_set_text(GTK_TEXT_BUFFER(localow->outputBuffer),
+ "\n\nWelcome to the test GUI:\nTest results are printed here\n\n", 58);
+ gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(localow->outputBuffer),
+ &localow->outputIter, 0);
+ *outwin = localow;
+ ow = *outwin;
+ }
+}
+
+/**
+ * _create_select_tests_window:
+ * @obj: An #AtkObject
+ * @runtest: The callback function that is run when the "Run Tests"
+ * button is clicked.
+ * @outwin: The output window to use.
+ *
+ * Creates the Test Select Window
+ *
+ * Returns: TRUE if successful, FALSE otherwise
+ **/
+static gboolean
+_create_select_tests_window (AtkObject *obj,
+ TLruntest runtest,
+ OutputWindow **outwin)
+{
+ AtkText *textwidget;
+ GtkWidget *hbuttonbox;
+ GtkWidget *scrolledWindow;
+
+ if (window_no >= 0 && window_no < MAX_WINDOWS)
+ {
+ md[window_no] = (MainDialog *) malloc (sizeof(MainDialog));
+
+ textwidget = ATK_TEXT (obj);
+
+ /* Setup Window */
+ md[window_no]->selecttestsTitle = "Test Setting";
+ md[window_no]->selecttestsWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title (GTK_WINDOW( ow->outputWindow),
+ md[window_no]->selecttestsTitle);
+ gtk_window_set_resizable (GTK_WINDOW(md[window_no]->selecttestsWindow),
+ FALSE);
+ gtk_window_set_position (GTK_WINDOW(md[window_no]->selecttestsWindow),
+ GTK_WIN_POS_CENTER);
+ g_signal_connect (GTK_OBJECT(md[window_no]->selecttestsWindow),
+ "destroy",
+ GTK_SIGNAL_FUNC(_destroy),
+ &md[window_no]->selecttestsWindow);
+
+ /* Setup Scrolling */
+ scrolledWindow = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledWindow),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_widget_set_usize (scrolledWindow, 500, 600);
+ gtk_container_add (GTK_CONTAINER (md[window_no]->selecttestsWindow),
+ scrolledWindow);
+
+ /* Setup Layout */
+ md[window_no]->vbox = gtk_vbox_new (TRUE, 0);
+ md[window_no]->button = gtk_button_new_with_mnemonic ("_Run Tests");
+ hbuttonbox = gtk_hbutton_box_new ();
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox),
+ GTK_BUTTONBOX_SPREAD);
+ gtk_box_pack_end_defaults (GTK_BOX (hbuttonbox),
+ GTK_WIDGET (md[window_no]->button));
+ gtk_box_pack_end_defaults (GTK_BOX (md[window_no]->vbox), hbuttonbox);
+ gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolledWindow),
+ md[window_no]->vbox);
+
+ testcb[window_no].runtest = runtest;
+ testcb[window_no].obj = obj;
+ testcb[window_no].win_num = window_no;
+ g_signal_connect (GTK_OBJECT (md[window_no]->button),
+ "clicked",
+ GTK_SIGNAL_FUNC (_testselectioncb),
+ (gpointer)&testcb[window_no]);
+
+ /* Show all */
+ gtk_widget_grab_focus (md[window_no]->button);
+ gtk_widget_show (md[window_no]->button);
+ gtk_widget_show (hbuttonbox);
+ gtk_widget_show (scrolledWindow);
+ gtk_widget_show_all (GTK_WIDGET (md[window_no]->selecttestsWindow));
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+/**
+ * add_test
+ * @window: The window number
+ * @name: The test name
+ * @num_params: The number of arguments the test uses.
+ * @parameter_names: The names of each argument.
+ * @default_names: The default values of each argument.
+ *
+ * Adds a Test with the passed-in details to the Tests Select Window.
+ *
+ * Returns: FALSE if the num_params passed in is greater than
+ * MAX_PARAMS, otherwise returns TRUE
+ *
+ **/
+gboolean
+add_test (gint window,
+ gchar *name,
+ gint num_params,
+ gchar* parameter_names[],
+ gchar* default_names[])
+{
+ gint i;
+
+ if (num_params > MAX_PARAMS)
+ return FALSE;
+ else
+ {
+ md[window]->hbox = gtk_hbox_new (FALSE, 0);
+ gtk_box_set_spacing (GTK_BOX (md[window]->hbox), 10);
+ gtk_container_set_border_width (GTK_CONTAINER (md[window]->hbox), 10);
+ gtk_container_add (GTK_CONTAINER (md[window]->vbox), md[window]->hbox);
+ listoftests[window][testcount[window]].toggleButton =
+ gtk_toggle_button_new_with_label (name);
+ gtk_box_pack_start (GTK_BOX (md[window]->hbox),
+ listoftests[window][testcount[window]].toggleButton, FALSE, FALSE, 0);
+ listoftests[window][testcount[window]].testName = name;
+ listoftests[window][testcount[window]].numParameters = num_params;
+ for (i=0; i<num_params; i++)
+ {
+ listoftests[window][testcount[window]].parameterLabel[i] =
+ gtk_label_new (parameter_names[i]);
+ gtk_box_pack_start (GTK_BOX (md[window]->hbox),
+ listoftests[window][testcount[window]].parameterLabel[i], FALSE, FALSE, 0);
+ listoftests[window][testcount[window]].parameterInput[i] = gtk_entry_new();
+ gtk_entry_set_text (GTK_ENTRY (listoftests[window][testcount[window]].parameterInput[i]),
+ default_names[i]);
+ gtk_widget_set_usize (listoftests[window][testcount[window]].parameterInput[i], 50, 22);
+ gtk_box_pack_start (GTK_BOX (md[window]->hbox),
+ listoftests[window][testcount[window]].parameterInput[i], FALSE, FALSE, 0);
+ gtk_widget_set_sensitive (
+ GTK_WIDGET (listoftests[window][testcount[window]].parameterLabel[i]), FALSE);
+ gtk_widget_set_sensitive (
+ GTK_WIDGET (listoftests[window][testcount[window]].parameterInput[i]), FALSE);
+ gtk_widget_show (listoftests[window][testcount[window]].parameterLabel[i]);
+ gtk_widget_show (listoftests[window][testcount[window]].parameterInput[i]);
+ }
+ g_signal_connect (GTK_OBJECT (listoftests[window][testcount[window]].toggleButton),
+ "toggled",
+ GTK_SIGNAL_FUNC(_toggle_selectedcb),
+ (gpointer)&(listoftests[window][testcount[window]]));
+ gtk_widget_show (listoftests[window][testcount[window]].toggleButton);
+ gtk_widget_show (md[window]->hbox);
+ gtk_widget_show (md[window]->vbox);
+
+ testcount[window]++;
+ counter++;
+ return TRUE;
+ }
+}
+
+/**
+ * tests_set:
+ * @window: The window number
+ * @count: Passes back the number of tests on.
+ *
+ * Gets an array of strings corresponding to the tests that are "on".
+ * A test is assumed on if the toggle button is on and if all its
+ * parameters have values.
+ *
+ * Returns: an array of strings corresponding to the tests that
+ * are "on".
+ **/
+gchar **tests_set(gint window, int *count)
+{
+ gint i =0, j = 0, num;
+ gboolean nullparam;
+ gchar* input;
+
+ *count = 0;
+ for (i = 0; i < MAX_TESTS; i++)
+ onTests[window][i] = NULL;
+
+ for (i = 0; i < testcount[window]; i++)
+ {
+ nullparam = FALSE;
+ if (GTK_TOGGLE_BUTTON(listoftests[window][i].toggleButton)->active)
+ {
+ num = listoftests[window][i].numParameters;
+ for (j = 0; j < num; j++)
+ {
+ input = gtk_editable_get_chars (
+ GTK_EDITABLE (listoftests[window][i].parameterInput[j]), 0, -1);
+
+ if (input != NULL && (! strcmp(input, "")))
+ nullparam = TRUE;
+ }
+ if (!nullparam)
+ {
+ onTests[window][*count] = listoftests[window][i].testName;
+ *count = *count + 1;
+ }
+ }
+ }
+ return onTests[window];
+}
+
+/**
+ * _get_position_in_array:
+ * @window: The window number
+ * @the_test_name: The name of the test
+ *
+ * Gets the index of the passed-in @the_test_name.
+ *
+ * Returns: the position in listoftests[] of @the_test_name
+ **/
+static gint
+_get_position_in_array(gint window,
+ gchar *the_test_name)
+{
+ gint i;
+
+ for (i = 0; i < testcount[window]; i++)
+ {
+ if (strcmp(listoftests[window][i].testName, the_test_name) == 0)
+ return i;
+ }
+ return -1;
+}
+
+/**
+ * _get_position_in_parameters:
+ * @window: The window number
+ * @label: The label name
+ * @position: The parameter position
+ *
+ * Gets the index of the passed-in parameter @label.
+ *
+ * Returns: the position in parameterLabel[] (a member of
+ * listoftests[]) of @label
+ **/
+static gint
+_get_position_in_parameters(gint window,
+ gchar *label,
+ gint position)
+{
+ gint i;
+ G_CONST_RETURN gchar *label_string;
+
+ for (i = 0; i < MAX_PARAMS; i++)
+ {
+ label_string = gtk_label_get_text(
+ GTK_LABEL (listoftests[window][position].parameterLabel[i]));
+
+ if (strcmp(label_string, label) == 0)
+ return i;
+ }
+ return -1;
+}
+
+/**
+ * set_output_buffer:
+ * @output: The string to add to the output buffer
+ *
+ * Tidies up the output Window
+ **/
+void
+set_output_buffer(gchar *output)
+{
+ gtk_text_buffer_insert (GTK_TEXT_BUFFER (ow->outputBuffer),
+ &ow->outputIter, output, strlen(output));
+ gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (ow->outputBuffer),
+ &ow->outputIter, 0);
+}
+
+/**
+ * isVisibleDialog:
+ *
+ * Informs user if a visible test window running.
+ *
+ * Returns: TRUE if g_visibleDialog is set to 1, otherwise FALSE
+ **/
+gboolean
+isVisibleDialog(void)
+{
+ if (g_visibleDialog >= 1)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/**
+ * get_arg_of_func:
+ * @window: The window number
+ * @function_name: The name of the function
+ * @arg_label: The label of the argument.
+ *
+ * Gets the user input associated with the @function_name and @arg_label.
+ *
+ * Returns: the user input associated with the @function_name and @arg_label.
+ **/
+gchar*
+get_arg_of_func (gint window,
+ gchar *function_name,
+ gchar *arg_label)
+{
+ G_CONST_RETURN gchar *argString;
+ gchar *retString;
+ gint position, paramPosition;
+
+ position = _get_position_in_array(window, function_name);
+
+ if (position == -1)
+ {
+ g_print("No such function\n");
+ return NULL;
+ }
+
+ paramPosition = _get_position_in_parameters(window, arg_label, position);
+
+ if (paramPosition == -1)
+ {
+ g_print("No such parameter Label\n");
+ return NULL;
+ }
+
+ if (position != -1 && paramPosition != -1)
+ {
+ argString = gtk_editable_get_chars (
+ GTK_EDITABLE (listoftests[window][position].parameterInput[paramPosition]),
+ 0, -1);
+ retString = g_strdup(argString);
+ }
+ else
+ retString = NULL;
+
+ return retString;
+}
+
+/**
+ * string_to_int:
+ * @the_string: The string to convert
+ *
+ * Converts the passed-in string to an integer
+ *
+ * Returns: An integer corresponding to @the_string.
+ **/
+int
+string_to_int (const char *the_string)
+{
+ char *end_ptr;
+ double ret_val;
+ int int_ret_val;
+
+ while (1)
+ {
+ ret_val = strtod( the_string, &end_ptr);
+ if (*end_ptr == '\0')
+ break;
+ else
+ printf("\nError: input must be a number\n");
+ }
+
+ int_ret_val = (int) ret_val;
+ return (int_ret_val);
+}
+
+/**
+ * _toggle_selectedcb:
+ * @widget: The ToggleButton widget
+ * @test: user data containing the TestList structure.
+ *
+ * Toggle Button Callback, activating the text entry fields
+ **/
+static void
+_toggle_selectedcb (GtkWidget *widget,
+ gpointer test)
+{
+ int i;
+ TestList *testlist = (TestList *) test;
+ gboolean toggled;
+ gboolean sensitive;
+ toggled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+ if (toggled)
+ sensitive = TRUE;
+ else
+ sensitive = FALSE;
+
+ for (i=0; i < testlist->numParameters; i++)
+ {
+ gtk_widget_set_sensitive (GTK_WIDGET (testlist->parameterLabel[i]),
+ sensitive);
+ gtk_widget_set_sensitive (GTK_WIDGET (testlist->parameterInput[i]),
+ sensitive);
+ }
+}
+
+/*
+ * _testselectioncb:
+ * widget: The Button widget
+ * data: The user data containing a TestCB structure
+ *
+ * Callback for when the "Run Tests" button is pressed
+ **/
+static void
+_testselectioncb (GtkWidget *widget,
+ gpointer data)
+{
+ TestCB* local_testcb = (TestCB *)data;
+ local_testcb->runtest(local_testcb->obj, local_testcb->win_num);
+}
+
+/**
+ * _destroy:
+ * @widget: The GUI widget
+ * @data: User data, not used.
+ *
+ * Destroy Callback.
+ **/
+static void
+_destroy (GtkWidget *widget,
+ gpointer data)
+{
+ gtk_main_quit();
+}
+
--- /dev/null
+#include <gtk/gtk.h>
+#include <stdio.h>
+
+/* Maximum characters in the output buffer */
+#define MAX_LINE_SIZE 1000
+
+/* Maximum number of tests */
+#define MAX_TESTS 30
+
+/* Maximum number of test windows */
+#define MAX_WINDOWS 5
+
+/* Maximum number of parameters any test can have */
+#define MAX_PARAMS 3
+
+/* Information on the Output Window */
+
+typedef struct
+{
+ GtkWidget *outputWindow;
+ GtkTextBuffer *outputBuffer;
+ GtkTextIter outputIter;
+}OutputWindow;
+
+typedef void (*TLruntest) (AtkObject * obj, gint win_num);
+
+/* General purpose functions */
+
+gboolean already_accessed_atk_object (AtkObject *obj);
+AtkObject* find_object_by_role (AtkObject *obj,
+ AtkRole *role,
+ gint num_roles);
+AtkObject* find_object_by_type (AtkObject *obj,
+ gchar *type);
+AtkObject* find_object_by_name_and_role (AtkObject *obj,
+ const gchar *name,
+ AtkRole *roles,
+ gint num_roles);
+AtkObject* find_object_by_accessible_name_and_role (AtkObject *obj,
+ const gchar *name,
+ AtkRole *roles,
+ gint num_roles);
+void display_children (AtkObject *obj,
+ gint depth,
+ gint child_number);
+void display_children_to_depth (AtkObject *obj,
+ gint to_depth,
+ gint depth,
+ gint child_number);
+
+
+/* Test GUI functions */
+
+gint create_windows (AtkObject *obj,
+ TLruntest runtest,
+ OutputWindow **outwin);
+gboolean add_test (gint window,
+ gchar *name,
+ gint num_params,
+ gchar *parameter_names[],
+ gchar *default_names[]);
+void set_output_buffer (gchar *output);
+gchar **tests_set (gint window,
+ int *count);
+gchar *get_arg_of_func (gint window,
+ gchar *function_name,
+ gchar *arg_label);
+int string_to_int (const char *the_string);
+gboolean isVisibleDialog (void);
+
--- /dev/null
+#include <string.h>
+#include <gtk/gtk.h>
+#include "testlib.h"
+
+/*
+ * This module is used to test the accessible implementation for menu items
+ *
+ * 1) When a menu item is clicked in testgtk, the action for the
+ * item is performed.
+ * 2) The name of the keybinding for the 'activate" action for a menu item
+ * is output, if it exists.
+ * 3) Execute the action for a menu item programatically
+ */
+#define NUM_VALID_ROLES 1
+
+static void _create_event_watcher (void);
+static void _check_object (AtkObject *obj);
+static gint _do_menu_item_action (gpointer data);
+
+static void
+_check_object (AtkObject *obj)
+{
+ AtkRole role;
+ static G_CONST_RETURN char *name = NULL;
+ static gboolean first_time = TRUE;
+
+ role = atk_object_get_role (obj);
+ if (role == ATK_ROLE_FRAME)
+ /*
+ * Find the specified menu item
+ */
+ {
+ AtkRole valid_roles[NUM_VALID_ROLES];
+ AtkObject *atk_menu_item;
+ GtkWidget *widget;
+
+ if (name == NULL)
+ {
+ valid_roles[0] = ATK_ROLE_MENU_ITEM;
+
+ name = g_getenv ("TEST_ACCESSIBLE_NAME");
+ if (name == NULL)
+ name = "foo";
+ }
+ atk_menu_item = find_object_by_accessible_name_and_role (obj, name,
+ valid_roles, NUM_VALID_ROLES);
+
+ if (atk_menu_item == NULL)
+ {
+ g_print ("Object not found for %s\n", name);
+ return;
+ }
+
+ g_assert (GTK_IS_ACCESSIBLE (atk_menu_item));
+ widget = GTK_ACCESSIBLE (atk_menu_item)->widget;
+ g_assert (GTK_IS_MENU_ITEM (widget));
+
+ if (first_time)
+ first_time = FALSE;
+ else
+ return;
+
+ /*
+ * This action opens the menu whose name is "foo" or whatever
+ * was specified in the environment variable TEST_ACCESSIBLE_NAME
+ */
+ atk_action_do_action (ATK_ACTION (atk_menu_item), 0);
+ }
+ else if ((role == ATK_ROLE_MENU_ITEM) ||
+ (role == ATK_ROLE_CHECK_MENU_ITEM) ||
+ (role == ATK_ROLE_RADIO_MENU_ITEM) ||
+ (role == ATK_ROLE_TEAR_OFF_MENU_ITEM))
+ {
+ G_CONST_RETURN char *keybinding;
+ G_CONST_RETURN char *accessible_name;
+
+ accessible_name = atk_object_get_name (obj);
+ if (accessible_name)
+ g_print ("Name: %s\n", accessible_name);
+ g_print ("Action: %s\n", atk_action_get_name (ATK_ACTION (obj), 0));
+ keybinding = atk_action_get_keybinding (ATK_ACTION (obj), 0);
+ if (keybinding)
+ g_print ("KeyBinding: %s\n", keybinding);
+ /*
+ * Do the action associated with the menu item once, otherwise
+ * we get into a loop
+ */
+ if (strcmp (name, accessible_name) == 0)
+ {
+ if (first_time)
+ first_time = FALSE;
+ else
+ return;
+ if (g_getenv ("TEST_ACCESSIBLE_AUTO"))
+ {
+ gtk_idle_add (_do_menu_item_action, obj);
+ }
+ }
+ }
+ else
+ {
+ G_CONST_RETURN char *accessible_name;
+
+ accessible_name = atk_object_get_name (obj);
+ if (accessible_name)
+ g_print ("Name: %s\n", accessible_name);
+ else if (GTK_IS_ACCESSIBLE (obj))
+ {
+ GtkWidget *widget = GTK_ACCESSIBLE (obj)->widget;
+ g_print ("Type: %s\n", g_type_name (G_OBJECT_TYPE (widget)));
+ }
+ }
+}
+
+static gint _do_menu_item_action (gpointer data)
+{
+ AtkObject *obj = ATK_OBJECT (data);
+
+ atk_action_do_action (ATK_ACTION (obj), 0);
+
+ return FALSE;
+}
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_check_object);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testmenuitem Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+
+#include <glib.h>
+#include <atk/atk.h>
+#include <atk/atkselection.h>
+#include <gtk/gtk.h>
+#include "testlib.h"
+
+#define NUM_VALID_ROLES 1
+
+static void _print_type (AtkObject *obj);
+static void _do_selection (AtkObject *obj);
+static gint _finish_selection (gpointer data);
+static gint _remove_page (gpointer data);
+
+static void _print_type (AtkObject *obj)
+{
+ G_CONST_RETURN gchar *typename = NULL;
+ G_CONST_RETURN gchar *name = NULL;
+ G_CONST_RETURN gchar *description = NULL;
+ AtkRole role;
+
+ if (GTK_IS_ACCESSIBLE (obj))
+ {
+ GtkWidget* widget = NULL;
+
+ widget = GTK_ACCESSIBLE (obj)->widget;
+ typename = g_type_name (GTK_OBJECT_TYPE (widget));
+ g_print ("\tWidget type name: %s\n", typename ? typename : "NULL");
+ }
+
+ typename = g_type_name (G_OBJECT_TYPE (obj));
+ g_print ("\tAccessible type name: %s\n", typename ? typename : "NULL");
+
+ name = atk_object_get_name (obj);
+ g_print("\tAccessible Name: %s\n", (name) ? name : "NULL");
+
+ role = atk_object_get_role(obj);
+ g_print ("\tAccessible Role: %d\n", role);
+
+ description = atk_object_get_description (obj);
+ g_print ("\tAccessible Description: %s\n", (description) ? description : "NULL");
+ if (role == ATK_ROLE_PAGE_TAB)
+ {
+ AtkObject *parent, *child;
+ gint x, y, width, height;
+
+ x = y = width = height = 0;
+ atk_component_get_extents (ATK_COMPONENT (obj), &x, &y, &width, &height,
+ ATK_XY_SCREEN);
+ g_print ("obj: x: %d y: %d width: %d height: %d\n", x, y, width, height);
+ x = y = width = height = 0;
+ atk_component_get_extents (ATK_COMPONENT (obj), &x, &y, &width, &height,
+ ATK_XY_WINDOW);
+ g_print ("obj: x: %d y: %d width: %d height: %d\n", x, y, width, height);
+ parent = atk_object_get_parent (obj);
+ x = y = width = height = 0;
+ atk_component_get_extents (ATK_COMPONENT (parent), &x, &y, &width, &height,
+ ATK_XY_SCREEN);
+ g_print ("parent: x: %d y: %d width: %d height: %d\n", x, y, width, height);
+ x = y = width = height = 0;
+ atk_component_get_extents (ATK_COMPONENT (parent), &x, &y, &width, &height,
+ ATK_XY_WINDOW);
+ g_print ("parent: x: %d y: %d width: %d height: %d\n", x, y, width, height);
+
+ child = atk_object_ref_accessible_child (obj, 0);
+ x = y = width = height = 0;
+ atk_component_get_extents (ATK_COMPONENT (child), &x, &y, &width, &height,
+ ATK_XY_SCREEN);
+ g_print ("child: x: %d y: %d width: %d height: %d\n", x, y, width, height);
+ x = y = width = height = 0;
+ atk_component_get_extents (ATK_COMPONENT (child), &x, &y, &width, &height,
+ ATK_XY_WINDOW);
+ g_print ("child: x: %d y: %d width: %d height: %d\n", x, y, width, height);
+
+ g_object_unref (child);
+ }
+}
+
+
+static void
+_do_selection (AtkObject *obj)
+{
+ gint i;
+ gint n_children;
+ AtkRole role;
+ AtkObject *selection_obj;
+ static gboolean done_selection = FALSE;
+
+ if (done_selection)
+ return;
+
+ role = atk_object_get_role (obj);
+
+ if (role == ATK_ROLE_FRAME)
+ {
+ AtkRole roles[NUM_VALID_ROLES];
+
+ roles[0] = ATK_ROLE_PAGE_TAB_LIST;
+
+ selection_obj = find_object_by_role (obj, roles, NUM_VALID_ROLES);
+
+ if (selection_obj)
+ {
+ done_selection = TRUE;
+ }
+ else
+ return;
+ }
+ else
+ {
+ return;
+ }
+
+ g_print ("*** Start do_selection ***\n");
+
+ n_children = atk_object_get_n_accessible_children (selection_obj);
+ g_print ("*** Number of notebook pages: %d\n", n_children);
+
+ for (i = 0; i < n_children; i++)
+ {
+ if (atk_selection_is_child_selected (ATK_SELECTION (selection_obj), i))
+ {
+ g_print ("%d page selected\n", i);
+ }
+ else
+ {
+ g_print ("%d page not selected\n", i);
+ }
+ }
+ /*
+ * Should not be able to select all items in a notebook.
+ */
+ atk_selection_select_all_selection (ATK_SELECTION (selection_obj));
+ i = atk_selection_get_selection_count (ATK_SELECTION (selection_obj));
+ if ( i != 1)
+ {
+ g_print ("Unexpected selection count: %d, expected 1\n", i);
+ g_print ("\t value of i is: %d\n", i);
+ return;
+ }
+
+ for (i = 0; i < n_children; i++)
+ {
+ atk_selection_add_selection (ATK_SELECTION (selection_obj), i);
+
+ if (atk_selection_is_child_selected (ATK_SELECTION (selection_obj), i))
+ {
+ g_print ("Page %d: successfully selected\n", i);
+ _finish_selection (selection_obj);
+ }
+ else
+ {
+ g_print ("ERROR: child %d: selection failed\n", i);
+ }
+ }
+ g_print ("*** End _do_selection ***\n");
+ gtk_timeout_add (5000, _remove_page, selection_obj);
+}
+
+static gint _remove_page (gpointer data)
+{
+ AtkObject *obj = ATK_OBJECT (data);
+ GtkWidget *widget = NULL;
+
+ if (GTK_IS_ACCESSIBLE (obj))
+ widget = GTK_ACCESSIBLE (obj)->widget;
+
+ g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
+ gtk_notebook_remove_page (GTK_NOTEBOOK (widget), 4);
+ return FALSE;
+}
+
+static gint _finish_selection (gpointer data)
+{
+ AtkObject *obj = ATK_OBJECT (data);
+ AtkObject *selected;
+ AtkObject *parent_object;
+ GtkWidget *parent_widget;
+ gint i, index;
+
+ g_print ("\t*** Start Finish selection ***\n");
+
+ i = atk_selection_get_selection_count (ATK_SELECTION (obj));
+ if (i != 1)
+ {
+ g_print ("\tUnexpected selection count: %d, expected 1\n", i);
+ return FALSE;
+ }
+ selected = atk_selection_ref_selection (ATK_SELECTION (obj), 0);
+ g_return_val_if_fail (selected != NULL, FALSE);
+
+ g_print ("\t*** Selected Item ***\n");
+ index = atk_object_get_index_in_parent (selected);
+ g_print ("\tIndex in parent is: %d\n", index);
+
+ parent_object = atk_object_get_parent (selected);
+ g_return_val_if_fail (ATK_IS_OBJECT (parent_object), FALSE);
+ g_return_val_if_fail (parent_object == obj, FALSE);
+ parent_widget = GTK_ACCESSIBLE (parent_object)->widget;
+ g_return_val_if_fail (GTK_IS_NOTEBOOK (parent_widget), FALSE);
+
+ _print_type (selected);
+ i = atk_selection_get_selection_count (ATK_SELECTION (obj));
+ g_return_val_if_fail (i == 1, FALSE);
+ g_object_unref (selected);
+ g_print ("\t*** End Finish selection ***\n");
+ return FALSE;
+}
+
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_do_selection);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testnotebook Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <gtk/gtk.h>
+#include "testlib.h"
+
+static void _print_accessible (AtkObject *obj);
+static void _print_type (AtkObject *obj);
+static void _print_states (AtkObject *obj);
+static void _check_children (AtkObject *obj);
+static void _check_relation (AtkObject *obj);
+static void _create_event_watcher (void);
+static void _focus_handler (AtkObject *obj, gboolean focus_in);
+static gboolean _children_changed (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data);
+
+static guint id;
+
+static void _print_states (AtkObject *obj)
+{
+ AtkStateSet *state_set;
+ gint i;
+
+ state_set = atk_object_ref_state_set (obj);
+
+ g_print ("*** Start states ***\n");
+ for (i = 0; i < 64; i++)
+ {
+ AtkStateType one_state;
+ G_CONST_RETURN gchar *name;
+
+ if (atk_state_set_contains_state (state_set, i))
+ {
+ one_state = i;
+
+ name = atk_state_type_get_name (one_state);
+
+ if (name)
+ g_print("%s\n", name);
+ }
+ }
+ g_object_unref (state_set);
+ g_print ("*** End states ***\n");
+}
+
+static void _print_type (AtkObject *obj)
+{
+ G_CONST_RETURN gchar * typename = NULL;
+ G_CONST_RETURN gchar * name = NULL;
+ AtkRole role;
+ static gboolean in_print_type = FALSE;
+
+ if (GTK_IS_ACCESSIBLE (obj))
+ {
+ GtkWidget* widget = NULL;
+
+ widget = GTK_ACCESSIBLE (obj)->widget;
+ typename = g_type_name (GTK_OBJECT_TYPE (widget));
+ g_print ("Widget type name: %s\n", typename ? typename : "NULL");
+ }
+ typename = g_type_name (G_OBJECT_TYPE (obj));
+ g_print ("Accessible type name: %s\n", typename ? typename : "NULL");
+ name = atk_object_get_name (obj);
+ g_print("Accessible Name: %s\n", (name) ? name : "NULL");
+ role = atk_object_get_role (obj);
+ g_print ("Accessible Role: %s\n", atk_role_get_name (role));
+
+ if (ATK_IS_COMPONENT (obj))
+ {
+ gint x, y, width, height;
+ AtkStateSet *states;
+
+ _print_states (obj);
+ states = atk_object_ref_state_set (obj);
+ if (atk_state_set_contains_state (states, ATK_STATE_VISIBLE))
+ {
+ AtkObject *parent;
+
+ atk_component_get_extents (ATK_COMPONENT (obj),
+ &x, &y, &width, &height,
+ ATK_XY_SCREEN);
+ g_print ("ATK_XY_SCREEN: x: %d y: %d width: %d height: %d\n",
+ x, y, width, height);
+
+ atk_component_get_extents (ATK_COMPONENT (obj),
+ &x, &y, &width, &height,
+ ATK_XY_WINDOW);
+ g_print ("ATK_XY_WINDOW: x: %d y: %d width: %d height: %d\n",
+ x, y, width, height);
+ if (atk_state_set_contains_state (states, ATK_STATE_SHOWING) &&
+ ATK_IS_TEXT (obj))
+ {
+ gint offset;
+
+ atk_text_get_character_extents (ATK_TEXT (obj), 1,
+ &x, &y, &width, &height,
+ ATK_XY_WINDOW);
+ g_print ("Character extents : %d %d %d %d\n",
+ x, y, width, height);
+ if (width != 0 && height != 0)
+ {
+ offset = atk_text_get_offset_at_point (ATK_TEXT (obj),
+ x, y,
+ ATK_XY_WINDOW);
+ if (offset != 1)
+ {
+ g_print ("Wrong offset returned (%d) %d\n", 1, offset);
+ }
+ }
+ }
+ if (in_print_type)
+ return;
+
+ parent = atk_object_get_parent (obj);
+ if (!ATK_IS_COMPONENT (parent))
+ {
+ /* Assume toplevel */
+ g_object_unref (G_OBJECT (states));
+ return;
+ }
+#if 0
+ obj1 = atk_component_ref_accessible_at_point (ATK_COMPONENT (parent),
+ x, y, ATK_XY_WINDOW);
+ if (obj != obj1)
+ {
+ g_print ("Inconsistency between object and ref_accessible_at_point\n");
+ in_print_type = TRUE;
+ _print_type (obj1);
+ in_print_type = FALSE;
+ }
+#endif
+ }
+ g_object_unref (G_OBJECT (states));
+ }
+}
+
+static void _print_accessible (AtkObject *obj)
+{
+ GtkWidget* widget = NULL;
+ AtkObject* parent_atk;
+ AtkObject* ref_obj;
+ AtkRole role;
+ static gboolean first_time = TRUE;
+
+ if (first_time)
+ {
+ first_time = FALSE;
+ atk_add_global_event_listener (_children_changed,
+ "Atk:AtkObject:children_changed");
+ }
+
+ /*
+ * Check that the object returned by the atk_implementor_ref_accessible()
+ * for a widget is the same as the accessible object
+ */
+ if (GTK_IS_ACCESSIBLE (obj))
+ {
+ widget = GTK_ACCESSIBLE (obj)->widget;
+ ref_obj = atk_implementor_ref_accessible (ATK_IMPLEMENTOR (widget));
+ g_assert (ref_obj == obj);
+ g_object_unref (G_OBJECT (ref_obj));
+ }
+ /*
+ * Add a focus handler so we see focus out events as well
+ */
+ if (ATK_IS_COMPONENT (obj))
+ atk_component_add_focus_handler (ATK_COMPONENT (obj), _focus_handler);
+ g_print ("Object:\n");
+ _print_type (obj);
+ _print_states (obj);
+
+ /*
+ * Get the parent object
+ */
+ parent_atk = atk_object_get_parent (obj);
+ if (parent_atk)
+ {
+ g_print ("Parent Object:\n");
+ _print_type (parent_atk);
+ parent_atk = atk_object_get_parent (parent_atk);
+ if (parent_atk)
+ {
+ g_print ("Grandparent Object:\n");
+ _print_type (parent_atk);
+ }
+ }
+ else
+ {
+ g_print ("No parent\n");
+ }
+
+ role = atk_object_get_role (obj);
+
+ if ((role == ATK_ROLE_FRAME) || (role == ATK_ROLE_DIALOG))
+ {
+ _check_children (obj);
+ }
+}
+
+static void _check_relation (AtkObject *obj)
+{
+ AtkRelationSet* relation_set = atk_object_ref_relation_set (obj);
+ gint n_relations, i;
+
+ g_return_if_fail (relation_set);
+
+ n_relations = atk_relation_set_get_n_relations (relation_set);
+ for (i = 0; i < n_relations; i++)
+ {
+ AtkRelation* relation = atk_relation_set_get_relation (relation_set, i);
+
+ g_print ("Index: %d Relation type: %d Number: %d\n", i,
+ atk_relation_get_relation_type (relation),
+ atk_relation_get_target (relation)->len);
+ }
+ g_object_unref (relation_set);
+}
+
+static void _check_children (AtkObject *obj)
+{
+ gint n_children, i;
+ AtkLayer layer;
+ AtkRole role;
+
+ g_print ("Start Check Children\n");
+ n_children = atk_object_get_n_accessible_children (obj);
+ g_print ("Number of children: %d\n", n_children);
+
+ role = atk_object_get_role (obj);
+
+ if (ATK_IS_COMPONENT (obj))
+ {
+ atk_component_add_focus_handler (ATK_COMPONENT (obj), _focus_handler);
+ layer = atk_component_get_layer (ATK_COMPONENT (obj));
+ if (role == ATK_ROLE_MENU)
+ g_assert (layer == ATK_LAYER_POPUP);
+ else
+ g_print ("Layer: %d\n", layer);
+ }
+
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject *child;
+ AtkObject *parent;
+ int j;
+
+ child = atk_object_ref_accessible_child (obj, i);
+ parent = atk_object_get_parent (child);
+ j = atk_object_get_index_in_parent (child);
+ _print_type (child);
+ _check_relation (child);
+ _check_children (child);
+ if (obj != parent)
+ {
+ g_print ("*** Inconsistency between atk_object_get_parent() and "
+ "atk_object_ref_accessible_child() ***\n");
+ _print_type (child);
+ _print_type (obj);
+ if (parent)
+ _print_type (parent);
+ }
+ g_object_unref (G_OBJECT (child));
+
+ if (j != i)
+ g_print ("*** Inconsistency between parent and children %d %d ***\n",
+ i, j);
+ }
+ g_print ("End Check Children\n");
+}
+
+static gboolean
+_children_changed (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GObject *object;
+ guint index;
+ gpointer target;
+ G_CONST_RETURN gchar *target_name = "NotAtkObject";
+
+ object = g_value_get_object (param_values + 0);
+ index = g_value_get_uint (param_values + 1);
+ target = g_value_get_pointer (param_values + 2);
+ if (G_IS_OBJECT (target))
+ {
+ if (ATK_IS_OBJECT (target))
+ {
+ target_name = atk_object_get_name (target);
+ }
+ if (!target_name)
+ target_name = g_type_name (G_OBJECT_TYPE (G_OBJECT (target)));
+ }
+ else
+ {
+ if (!target)
+ {
+ AtkObject *child;
+
+ child = atk_object_ref_accessible_child (ATK_OBJECT (object), index);
+ if (child)
+ {
+ target_name = g_type_name (G_OBJECT_TYPE (G_OBJECT (child)));
+ g_object_unref (child);
+ }
+ }
+ }
+ g_print ("_children_watched: %s %s %s index: %d\n",
+ g_type_name (G_OBJECT_TYPE (object)),
+ g_quark_to_string (ihint->detail),
+ target_name, index);
+ return TRUE;
+}
+
+static void
+_create_event_watcher (void)
+{
+ /*
+ * _print_accessible() will be called for an accessible object when its
+ * widget receives focus.
+ */
+ id = atk_add_focus_tracker (_print_accessible);
+}
+
+static void
+_focus_handler (AtkObject *obj, gboolean focus_in)
+{
+ g_print ("In _focus_handler focus_in: %s\n", focus_in ? "true" : "false");
+ _print_type (obj);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testobject Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <gtk/gtk.h>
+#include "testlib.h"
+
+/*
+ * This module is used to test the accessible implementation for GtkOptionMenu
+ *
+ * When the GtkOption menu in the FileSelectionDialog is tabbed to, the menu
+ * is opened and the second item in the menu is selected which causes the
+ * menu to be closed and the item in the GtkOptionMenu to be updated.
+ */
+#define NUM_VALID_ROLES 1
+
+static void _create_event_watcher (void);
+static void _check_object (AtkObject *obj);
+static gint _do_menu_item_action (gpointer data);
+static gboolean doing_action = FALSE;
+
+static void
+_check_object (AtkObject *obj)
+{
+ AtkRole role;
+ static G_CONST_RETURN char *name = NULL;
+ static gboolean first_time = TRUE;
+
+ role = atk_object_get_role (obj);
+ if (role == ATK_ROLE_PUSH_BUTTON)
+ /*
+ * Find the specified optionmenu item
+ */
+ {
+ AtkRole valid_roles[NUM_VALID_ROLES];
+ AtkObject *atk_option_menu;
+ GtkWidget *widget;
+
+ if (name == NULL)
+ {
+ name = g_getenv ("TEST_ACCESSIBLE_NAME");
+ if (name == NULL)
+ name = "foo";
+ }
+ valid_roles[0] = ATK_ROLE_PUSH_BUTTON;
+ atk_option_menu = find_object_by_accessible_name_and_role (obj, name,
+ valid_roles, NUM_VALID_ROLES);
+
+ if (atk_option_menu == NULL)
+ {
+ g_print ("Object not found for %s\n", name);
+ return;
+ }
+ else
+ {
+ g_print ("Object found for %s\n", name);
+ }
+
+
+ g_assert (GTK_IS_ACCESSIBLE (atk_option_menu));
+ widget = GTK_ACCESSIBLE (atk_option_menu)->widget;
+ g_assert (GTK_IS_OPTION_MENU (widget));
+
+ if (first_time)
+ first_time = FALSE;
+ else
+ return;
+
+ /*
+ * This action opens the GtkOptionMenu whose name is "foo" or whatever
+ * was specified in the environment variable TEST_ACCESSIBLE_NAME
+ */
+ atk_action_do_action (ATK_ACTION (atk_option_menu), 0);
+ }
+ else if ((role == ATK_ROLE_MENU_ITEM) ||
+ (role == ATK_ROLE_CHECK_MENU_ITEM) ||
+ (role == ATK_ROLE_RADIO_MENU_ITEM) ||
+ (role == ATK_ROLE_TEAR_OFF_MENU_ITEM))
+ {
+ AtkObject *parent, *child;
+ AtkRole parent_role;
+
+ /*
+ * If we receive focus while waiting for the menu to be closed
+ * we return immediately
+ */
+ if (doing_action)
+ return;
+
+ parent = atk_object_get_parent (obj);
+ parent_role = atk_object_get_role (parent);
+ g_assert (parent_role == ATK_ROLE_MENU);
+
+ child = atk_object_ref_accessible_child (parent, 1);
+ doing_action = TRUE;
+ gtk_timeout_add (5000, _do_menu_item_action, child);
+ }
+ else
+ {
+ G_CONST_RETURN char *accessible_name;
+
+ accessible_name = atk_object_get_name (obj);
+ if (accessible_name)
+ {
+ g_print ("Name: %s\n", accessible_name);
+ }
+ else if (GTK_IS_ACCESSIBLE (obj))
+ {
+ GtkWidget *widget = GTK_ACCESSIBLE (obj)->widget;
+ g_print ("Type: %s\n", g_type_name (G_OBJECT_TYPE (widget)));
+ }
+ if (role == ATK_ROLE_TABLE)
+ {
+ gint n_cols, i;
+
+ n_cols = atk_table_get_n_columns (ATK_TABLE (obj));
+ g_print ("Number of Columns: %d\n", n_cols);
+
+ for (i = 0; i < n_cols; i++)
+ {
+ AtkObject *header;
+
+ header = atk_table_get_column_header (ATK_TABLE (obj), i);
+ g_print ("header: %s %s\n",
+ g_type_name (G_OBJECT_TYPE (header)),
+ atk_object_get_name (header));
+ }
+ }
+ }
+}
+
+static gint _do_menu_item_action (gpointer data)
+{
+ AtkObject *obj = ATK_OBJECT (data);
+
+ atk_action_do_action (ATK_ACTION (obj), 0);
+ doing_action = FALSE;
+
+ g_object_unref (obj);
+
+ return FALSE;
+}
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_check_object);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testoptionmenu Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <string.h>
+#include <stdlib.h>
+#include <gtk/gtk.h>
+#include <testlib.h>
+
+static gint _test_paned (gpointer data);
+static void _check_paned (AtkObject *obj);
+
+static void _property_change_handler (AtkObject *obj,
+ AtkPropertyValues *values);
+
+#define NUM_VALID_ROLES 1
+static gint last_position;
+
+static void _property_change_handler (AtkObject *obj,
+ AtkPropertyValues *values)
+{
+ G_CONST_RETURN gchar *type_name = g_type_name (G_TYPE_FROM_INSTANCE (obj));
+ G_CONST_RETURN gchar *name = atk_object_get_name (obj);
+
+ g_print ("_property_change_handler: Accessible Type: %s\n",
+ type_name ? type_name : "NULL");
+ g_print ("_property_change_handler: Accessible name: %s\n",
+ name ? name : "NULL");
+ g_print ("_property_change_handler: PropertyName: %s\n",
+ values->property_name ? values->property_name: "NULL");
+ if (strcmp (values->property_name, "accessible-value") == 0)
+ {
+ GValue *value, val;
+ int position;
+ value = &val;
+
+ memset (value, 0, sizeof (GValue));
+ atk_value_get_current_value (ATK_VALUE (obj), value);
+ g_return_if_fail (G_VALUE_HOLDS_INT (value));
+ position = g_value_get_int (value);
+ g_print ("Position is %d previous position was %d\n",
+ position, last_position);
+ last_position = position;
+ atk_value_get_minimum_value (ATK_VALUE (obj), value);
+ g_return_if_fail (G_VALUE_HOLDS_INT (value));
+ position = g_value_get_int (value);
+ g_print ("Minimum Value is %d\n", position);
+ atk_value_get_maximum_value (ATK_VALUE (obj), value);
+ g_return_if_fail (G_VALUE_HOLDS_INT (value));
+ position = g_value_get_int (value);
+ g_print ("Maximum Value is %d\n", position);
+ }
+}
+
+static gint _test_paned (gpointer data)
+{
+ AtkObject *obj = ATK_OBJECT (data);
+ AtkRole role = atk_object_get_role (obj);
+ GtkWidget *widget;
+ static gint times = 0;
+
+ widget = GTK_ACCESSIBLE (obj)->widget;
+
+ if (role == ATK_ROLE_SPLIT_PANE)
+ {
+ GValue *value, val;
+ int position;
+ value = &val;
+
+ memset (value, 0, sizeof (GValue));
+ atk_value_get_current_value (ATK_VALUE (obj), value);
+ g_return_val_if_fail (G_VALUE_HOLDS_INT (value), FALSE);
+ position = g_value_get_int (value);
+ g_print ("Position is : %d\n", position);
+ last_position = position;
+ position *= 2;
+ g_value_set_int (value, position);
+ atk_value_set_current_value (ATK_VALUE (obj), value);
+ times++;
+ }
+ if (times < 4)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static void _check_paned (AtkObject *obj)
+{
+ static gboolean done_paned = FALSE;
+ AtkRole role;
+
+ role = atk_object_get_role (obj);
+
+ if (role == ATK_ROLE_FRAME)
+ {
+ AtkRole roles[NUM_VALID_ROLES];
+ AtkObject *paned_obj;
+
+ if (done_paned)
+ return;
+
+ roles[0] = ATK_ROLE_SPLIT_PANE;
+
+ paned_obj = find_object_by_role (obj, roles, NUM_VALID_ROLES);
+
+ if (paned_obj)
+ {
+ if (!done_paned)
+ {
+ done_paned = TRUE;
+ }
+ atk_object_connect_property_change_handler (paned_obj,
+ (AtkPropertyChangeHandler*) _property_change_handler);
+ gtk_timeout_add (2000, _test_paned, paned_obj);
+ }
+
+ return;
+ }
+ if (role != ATK_ROLE_COMBO_BOX)
+ return;
+}
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_check_paned);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testpaned Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <string.h>
+#include <stdlib.h>
+#include <atk/atk.h>
+#include <gtk/gtk.h>
+#include <testlib.h>
+
+static void _traverse_children (AtkObject *obj);
+static void _add_handler (AtkObject *obj);
+static void _check_properties (AtkObject *obj);
+static void _property_change_handler (AtkObject *obj,
+ AtkPropertyValues *values);
+static void _state_changed (AtkObject *obj,
+ const gchar *name,
+ gboolean set);
+static void _selection_changed (AtkObject *obj);
+static void _visible_data_changed (AtkObject *obj);
+static void _model_changed (AtkObject *obj);
+static void _create_event_watcher (void);
+
+static guint id;
+
+static void
+_state_changed (AtkObject *obj,
+ const gchar *name,
+ gboolean set)
+{
+ g_print ("_state_changed: %s: state %s %s\n",
+ g_type_name (G_OBJECT_TYPE (obj)),
+ set ? "is" : "was", name);
+}
+
+static void
+_selection_changed (AtkObject *obj)
+{
+ gchar *type;
+
+ if (ATK_IS_TEXT (obj))
+ type = "text";
+ else if (ATK_IS_SELECTION (obj))
+ type = "child selection";
+ else
+ {
+ g_assert_not_reached();
+ return;
+ }
+
+ g_print ("In selection_changed signal handler for %s, object type: %s\n",
+ type, g_type_name (G_OBJECT_TYPE (obj)));
+}
+
+static void
+_visible_data_changed (AtkObject *obj)
+{
+ g_print ("In visible_data_changed signal handler, object type: %s\n",
+ g_type_name (G_OBJECT_TYPE (obj)));
+}
+
+static void
+_model_changed (AtkObject *obj)
+{
+ g_print ("In model_changed signal handler, object type: %s\n",
+ g_type_name (G_OBJECT_TYPE (obj)));
+}
+
+static void
+_property_change_handler (AtkObject *obj,
+ AtkPropertyValues *values)
+{
+ G_CONST_RETURN gchar *type_name = g_type_name (G_TYPE_FROM_INSTANCE (obj));
+ G_CONST_RETURN gchar *name = atk_object_get_name (obj);
+
+ g_print ("_property_change_handler: Accessible Type: %s\n",
+ type_name ? type_name : "NULL");
+ g_print ("_property_change_handler: Accessible name: %s\n",
+ name ? name : "NULL");
+ g_print ("_property_change_handler: PropertyName: %s\n",
+ values->property_name ? values->property_name: "NULL");
+ if (G_VALUE_HOLDS_STRING (&values->new_value))
+ g_print ("_property_change_handler: PropertyValue: %s\n",
+ g_value_get_string (&values->new_value));
+ else if (strcmp (values->property_name, "accessible-child") == 0)
+ {
+ if (G_IS_VALUE (&values->old_value))
+ {
+ g_print ("Child is removed: %s\n",
+ g_type_name (G_TYPE_FROM_INSTANCE (g_value_get_pointer (&values->old_value))));
+ }
+ if (G_IS_VALUE (&values->new_value))
+ {
+ g_print ("Child is added: %s\n",
+ g_type_name (G_TYPE_FROM_INSTANCE (g_value_get_pointer (&values->new_value))));
+ }
+ }
+ else if (strcmp (values->property_name, "accessible-parent") == 0)
+ {
+ if (G_IS_VALUE (&values->old_value))
+ {
+ g_print ("Parent is removed: %s\n",
+ g_type_name (G_TYPE_FROM_INSTANCE (g_value_get_pointer (&values->old_value))));
+ }
+ if (G_IS_VALUE (&values->new_value))
+ {
+ g_print ("Parent is added: %s\n",
+ g_type_name (G_TYPE_FROM_INSTANCE (g_value_get_pointer (&values->new_value))));
+ }
+ }
+ else if (strcmp (values->property_name, "accessible-value") == 0)
+ {
+ if (G_VALUE_HOLDS_DOUBLE (&values->new_value))
+ {
+ g_print ("Value now is (double) %f\n",
+ g_value_get_double (&values->new_value));
+ }
+ }
+}
+
+static void
+_traverse_children (AtkObject *obj)
+{
+ gint n_children, i;
+ AtkRole role;
+
+ role = atk_object_get_role (obj);
+
+ if ((role == ATK_ROLE_TABLE) ||
+ (role == ATK_ROLE_TREE_TABLE))
+ return;
+
+ n_children = atk_object_get_n_accessible_children (obj);
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject *child;
+
+ child = atk_object_ref_accessible_child (obj, i);
+ _add_handler (child);
+ _traverse_children (child);
+ g_object_unref (G_OBJECT (child));
+ }
+}
+
+static void
+_add_handler (AtkObject *obj)
+{
+ static GPtrArray *obj_array = NULL;
+ gboolean found = FALSE;
+ gint i;
+
+ /*
+ * We create a property handler for each object if one was not associated
+ * with it already.
+ *
+ * We add it to our array of objects which have property handlers; if an
+ * object is destroyed it remains in the array.
+ */
+ if (obj_array == NULL)
+ obj_array = g_ptr_array_new ();
+
+ for (i = 0; i < obj_array->len; i++)
+ {
+ if (obj == g_ptr_array_index (obj_array, i))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found)
+ {
+ atk_object_connect_property_change_handler (obj,
+ (AtkPropertyChangeHandler*) _property_change_handler);
+ g_signal_connect (obj, "state-change",
+ (GCallback) _state_changed, NULL);
+ if (ATK_IS_SELECTION (obj))
+ g_signal_connect (obj, "selection_changed",
+ (GCallback) _selection_changed, NULL);
+ g_signal_connect (obj, "visible_data_changed",
+ (GCallback) _visible_data_changed, NULL);
+ if (ATK_IS_TABLE (obj))
+ g_signal_connect (obj, "model_changed",
+ (GCallback) _model_changed, NULL);
+ g_ptr_array_add (obj_array, obj);
+ }
+}
+
+static void
+_check_properties (AtkObject *obj)
+{
+ AtkRole role;
+
+ g_print ("Start of _check_properties: %s\n",
+ g_type_name (G_OBJECT_TYPE (obj)));
+
+ _add_handler (obj);
+
+ role = atk_object_get_role (obj);
+ if (role == ATK_ROLE_FRAME ||
+ role == ATK_ROLE_DIALOG)
+ {
+ /*
+ * Add handlers to all children.
+ */
+ _traverse_children (obj);
+ }
+ g_print ("End of _check_properties\n");
+}
+
+static void
+_create_event_watcher (void)
+{
+ id = atk_add_focus_tracker (_check_properties);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testprops Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <string.h>
+#include <atk/atk.h>
+#include <gtk/gtk.h>
+
+/*
+ * This module tests the selection interface on menu items.
+ * To use this module run the test program testgtk and use the menus
+ * option.
+ */
+static void _do_selection (AtkObject *obj);
+static gint _finish_selection (gpointer data);
+static AtkObject* _find_object (AtkObject* obj, AtkRole role);
+static void _print_type (AtkObject *obj);
+
+static AtkObject*
+_find_object (AtkObject *obj,
+ AtkRole role)
+{
+ /*
+ * Find the first object which is a descendant of the specified object
+ * which matches the specified role.
+ *
+ * This function returns a reference to the AtkObject which should be
+ * removed when finished with the object.
+ */
+ gint i;
+ gint n_children;
+ AtkObject *child;
+
+ n_children = atk_object_get_n_accessible_children (obj);
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject* found_obj;
+
+ child = atk_object_ref_accessible_child (obj, i);
+ if (atk_object_get_role (child) == role)
+ {
+ return child;
+ }
+ found_obj = _find_object (child, role);
+ g_object_unref (child);
+ if (found_obj)
+ {
+ return found_obj;
+ }
+ }
+ return NULL;
+}
+
+static void _print_type (AtkObject *obj)
+{
+ G_CONST_RETURN gchar * typename = NULL;
+ G_CONST_RETURN gchar * name = NULL;
+ AtkRole role;
+
+ if (GTK_IS_ACCESSIBLE (obj))
+ {
+ GtkWidget* widget = NULL;
+
+ widget = GTK_ACCESSIBLE (obj)->widget;
+ typename = g_type_name (GTK_OBJECT_TYPE (widget));
+ g_print ("Widget type name: %s\n", typename ? typename : "NULL");
+ }
+ typename = g_type_name (G_OBJECT_TYPE (obj));
+ g_print ("Accessible type name: %s\n", typename ? typename : "NULL");
+ name = atk_object_get_name (obj);
+ g_print("Accessible Name: %s\n", (name) ? name : "NULL");
+ role = atk_object_get_role(obj);
+ g_print ("Accessible Role: %d\n", role);
+}
+
+static void
+_do_selection (AtkObject *obj)
+{
+ gint i;
+ AtkObject *selected;
+ AtkRole role;
+ AtkObject *selection_obj;
+
+ role = atk_object_get_role (obj);
+
+ if ((role == ATK_ROLE_FRAME) &&
+ (strcmp (atk_object_get_name (obj), "menus") == 0))
+ {
+ selection_obj = _find_object (obj, ATK_ROLE_MENU_BAR);
+ if (selection_obj)
+ {
+ g_object_unref (selection_obj);
+ }
+ }
+ else if (role == ATK_ROLE_COMBO_BOX)
+ {
+ selection_obj = obj;
+ }
+ else
+ return;
+
+ g_print ("*** Start do_selection ***\n");
+
+
+ if (!selection_obj)
+ {
+ g_print ("no selection_obj\n");
+ return;
+ }
+
+ i = atk_selection_get_selection_count (ATK_SELECTION (selection_obj));
+ if (i != 0)
+ {
+ for (i = 0; i < atk_object_get_n_accessible_children (selection_obj); i++)
+ {
+ if (atk_selection_is_child_selected (ATK_SELECTION (selection_obj), i))
+ {
+ g_print ("%d child selected\n", i);
+ }
+ else
+ {
+ g_print ("%d child not selected\n", i);
+ }
+ }
+ }
+ /*
+ * Should not be able to select all items on a menu bar
+ */
+ atk_selection_select_all_selection (ATK_SELECTION (selection_obj));
+ i = atk_selection_get_selection_count (ATK_SELECTION (selection_obj));
+ if ( i != 0)
+ {
+ g_print ("Unexpected selection count: %d, expected 0\n", i);
+ return;
+ }
+ /*
+ * There should not be any items selected
+ */
+ selected = atk_selection_ref_selection (ATK_SELECTION (selection_obj), 0);
+ if ( selected != NULL)
+ {
+ g_print ("Unexpected selection: %d, expected 0\n", i);
+ }
+ atk_selection_add_selection (ATK_SELECTION (selection_obj), 1);
+ gtk_timeout_add (2000, _finish_selection, selection_obj);
+ g_print ("*** End _do_selection ***\n");
+}
+
+static gint _finish_selection (gpointer data)
+{
+ AtkObject *obj = ATK_OBJECT (data);
+ AtkObject *selected;
+ gint i;
+ gboolean is_selected;
+
+ g_print ("*** Start Finish selection ***\n");
+
+ /*
+ * If being run for for menus, at this point menu item foo should be
+ * selected which means that its submenu should be visible.
+ */
+ i = atk_selection_get_selection_count (ATK_SELECTION (obj));
+ if (i != 1)
+ {
+ g_print ("Unexpected selection count: %d, expected 1\n", i);
+ return FALSE;
+ }
+ selected = atk_selection_ref_selection (ATK_SELECTION (obj), 0);
+ g_return_val_if_fail (selected != NULL, FALSE);
+ g_print ("*** Selected Item ***\n");
+ _print_type (selected);
+ g_object_unref (selected);
+ is_selected = atk_selection_is_child_selected (ATK_SELECTION (obj), 1);
+ g_return_val_if_fail (is_selected, FALSE);
+ is_selected = atk_selection_is_child_selected (ATK_SELECTION (obj), 0);
+ g_return_val_if_fail (!is_selected, FALSE);
+ selected = atk_selection_ref_selection (ATK_SELECTION (obj), 1);
+ g_return_val_if_fail (selected == NULL, FALSE);
+ atk_selection_remove_selection (ATK_SELECTION (obj), 0);
+ i = atk_selection_get_selection_count (ATK_SELECTION (obj));
+ g_return_val_if_fail (i == 0, FALSE);
+ selected = atk_selection_ref_selection (ATK_SELECTION (obj), 0);
+ g_return_val_if_fail (selected == NULL, FALSE);
+ g_print ("*** End Finish selection ***\n");
+ return FALSE;
+}
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_do_selection);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testselection Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <string.h>
+#include <glib-object.h>
+#include <atk/atk.h>
+
+/*
+ * To use this test module, run the test program testgtk and click on
+ * statusbar
+ */
+
+static void _check_statusbar (AtkObject *obj);
+static AtkObject* _find_object (AtkObject* obj, AtkRole role);
+static void _notify_handler (GObject *obj, GParamSpec *pspec);
+static void _property_change_handler (AtkObject *obj,
+ AtkPropertyValues *values);
+
+static AtkObject*
+_find_object (AtkObject *obj,
+ AtkRole role)
+{
+ /*
+ * Find the first object which is a descendant of the specified object
+ * which matches the specified role.
+ *
+ * This function returns a reference to the AtkObject which should be
+ * removed when finished with the object.
+ */
+ gint i;
+ gint n_children;
+ AtkObject *child;
+
+ n_children = atk_object_get_n_accessible_children (obj);
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject* found_obj;
+
+ child = atk_object_ref_accessible_child (obj, i);
+ if (atk_object_get_role (child) == role)
+ {
+ return child;
+ }
+ found_obj = _find_object (child, role);
+ g_object_unref (child);
+ if (found_obj)
+ {
+ return found_obj;
+ }
+ }
+ return NULL;
+}
+
+static void _property_change_handler (AtkObject *obj,
+ AtkPropertyValues *values)
+{
+ G_CONST_RETURN gchar *type_name = g_type_name (G_TYPE_FROM_INSTANCE (obj));
+ G_CONST_RETURN gchar *name = atk_object_get_name (obj);
+
+ g_print ("_property_change_handler: Accessible Type: %s\n",
+ type_name ? type_name : "NULL");
+ g_print ("_property_change_handler: Accessible name: %s\n",
+ name ? name : "NULL");
+ g_print ("_property_change_handler: PropertyName: %s\n",
+ values->property_name ? values->property_name: "NULL");
+ if (G_VALUE_HOLDS_STRING (&values->new_value))
+ g_print ("_property_change_handler: PropertyValue: %s\n",
+ g_value_get_string (&values->new_value));
+}
+
+static void _check_statusbar (AtkObject *obj)
+{
+ AtkRole role;
+ AtkObject *statusbar, *label;
+
+ role = atk_object_get_role (obj);
+ if (role != ATK_ROLE_FRAME)
+ return;
+
+ statusbar = _find_object (obj, ATK_ROLE_STATUSBAR);
+ if (!statusbar)
+ return;
+ g_print ("_check_statusbar\n");
+ label = atk_object_ref_accessible_child (statusbar, 0);
+ g_return_if_fail (label == NULL);
+
+ /*
+ * We get notified of changes to the label
+ */
+ g_signal_connect_closure_by_id (statusbar,
+ g_signal_lookup ("notify",
+ G_OBJECT_TYPE (statusbar)),
+ 0,
+ g_cclosure_new (G_CALLBACK (_notify_handler),
+ NULL, NULL),
+ FALSE);
+ atk_object_connect_property_change_handler (statusbar,
+ (AtkPropertyChangeHandler*) _property_change_handler);
+
+}
+
+static void
+_notify_handler (GObject *obj, GParamSpec *pspec)
+{
+ AtkObject *atk_obj = ATK_OBJECT (obj);
+ G_CONST_RETURN gchar *name;
+
+ g_print ("_notify_handler: property: %s\n", pspec->name);
+ if (strcmp (pspec->name, "accessible-name") == 0)
+ {
+ name = atk_object_get_name (atk_obj);
+ g_print ("_notify_handler: value: |%s|\n", name ? name : "<NULL>");
+ }
+}
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_check_statusbar);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("teststatusbar Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <string.h>
+#include "testtextlib.h"
+
+#define NUM_ROWS_TO_LOOP 30
+
+typedef struct
+{
+ GtkWidget *tb_others;
+ GtkWidget *tb_ref_selection;
+ GtkWidget *tb_ref_at;
+ GtkWidget *tb_ref_accessible_child;
+ GtkWidget *child_entry;
+ GtkWidget *row_entry;
+ GtkWidget *col_entry;
+ GtkWidget *index_entry;
+}TestChoice;
+
+static void _check_table (AtkObject *in_obj);
+void table_runtest(AtkObject *);
+static void other_runtest(AtkObject *obj);
+static void ref_at_runtest(AtkObject *obj, gint row, gint col);
+static void ref_accessible_child_runtest(AtkObject *obj, gint childno);
+static void ref_selection_runtest (AtkObject *obj, gint index);
+static void _selection_tests(AtkObject *obj);
+static void _display_header_info(gchar *type,
+ AtkObject *header_obj, gint header_num);
+static void _process_child(AtkObject *child_obj);
+
+static void _notify_table_row_inserted (GObject *obj,
+ gint start_offset, gint length);
+static void _notify_table_column_inserted (GObject *obj,
+ gint start_offset, gint length);
+static void _notify_table_row_deleted (GObject *obj,
+ gint start_offset, gint length);
+static void _notify_table_column_deleted (GObject *obj,
+ gint start_offset, gint length);
+static void _notify_table_row_reordered (GObject *obj);
+static void _notify_table_column_reordered (GObject *obj);
+static void _notify_table_child_added (GObject *obj,
+ gint index, AtkObject *child);
+static void _notify_table_child_removed (GObject *obj,
+ gint index, AtkObject *child);
+static void _property_signal_connect (AtkObject *obj);
+static void _property_change_handler (AtkObject *obj,
+ AtkPropertyValues *values);
+
+static gboolean tested_set_headers = FALSE;
+static void test_choice_gui (AtkObject **obj);
+static void nogui_runtest (AtkObject *obj);
+static void nogui_ref_at_runtest (AtkObject *obj);
+static void nogui_process_child (AtkObject *obj);
+
+static TestChoice *tc;
+static gint g_visibleGUI = 0;
+static AtkTable *g_table = NULL;
+static AtkObject *current_obj = NULL;
+gboolean g_done = FALSE;
+gboolean g_properties = TRUE;
+
+/*
+ * destroy
+ *
+ * Destroy Callback
+ *
+ */
+static void destroy (GtkWidget *widget, gpointer data)
+{
+ gtk_main_quit();
+}
+
+static void choicecb (GtkWidget *widget, gpointer data)
+{
+ AtkObject **ptr_to_obj = (AtkObject **)data;
+ AtkObject *obj = *ptr_to_obj;
+
+ if (GTK_TOGGLE_BUTTON(tc->tb_others)->active)
+ {
+ other_runtest(obj);
+ }
+ else if (GTK_TOGGLE_BUTTON(tc->tb_ref_selection)->active)
+ {
+ const gchar *indexstr;
+ gint index;
+
+ indexstr = gtk_entry_get_text(GTK_ENTRY(tc->index_entry));
+ index = string_to_int((gchar *)indexstr);
+
+ ref_selection_runtest(obj, index);
+ }
+ else if (GTK_TOGGLE_BUTTON(tc->tb_ref_at)->active)
+ {
+ const gchar *rowstr, *colstr;
+ gint row, col;
+
+ rowstr = gtk_entry_get_text(GTK_ENTRY(tc->row_entry));
+ colstr = gtk_entry_get_text(GTK_ENTRY(tc->col_entry));
+ row = string_to_int((gchar *)rowstr);
+ col = string_to_int((gchar *)colstr);
+
+ ref_at_runtest(obj, row, col);
+ }
+ else if (GTK_TOGGLE_BUTTON(tc->tb_ref_accessible_child)->active)
+ {
+ const gchar *childstr;
+ gint childno;
+ childstr = gtk_entry_get_text(GTK_ENTRY(tc->child_entry));
+ childno = string_to_int((gchar *)childstr);
+
+ ref_accessible_child_runtest(obj, childno);
+ }
+}
+
+static void _check_table (AtkObject *in_obj)
+{
+ AtkObject *obj = NULL;
+ G_CONST_RETURN char *no_properties;
+ G_CONST_RETURN char *no_gui;
+
+ no_properties = g_getenv ("TEST_ACCESSIBLE_NO_PROPERTIES");
+ no_gui = g_getenv ("TEST_ACCESSIBLE_NO_GUI");
+
+ if (no_properties != NULL)
+ g_properties = FALSE;
+ if (no_gui != NULL)
+ g_visibleGUI = 1;
+
+ obj = find_object_by_type(in_obj, "GailTreeView");
+ if (obj != NULL)
+ g_print("Found GailTreeView table in child!\n");
+ else
+ {
+ obj = find_object_by_type(in_obj, "GailCList");
+ if (obj != NULL)
+ g_print("Found GailCList in child!\n");
+ else
+ {
+ g_print("No object found %s\n", g_type_name (G_OBJECT_TYPE (in_obj)));
+ return;
+ }
+ }
+
+ g_print ("In _check_table\n");
+
+ if (!already_accessed_atk_object(obj))
+ {
+ /* Set up signal handlers */
+
+ g_print ("Adding signal handler\n");
+ g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("column_inserted", G_OBJECT_TYPE (obj)),
+ 0,
+ g_cclosure_new (G_CALLBACK (_notify_table_column_inserted),
+ NULL, NULL),
+ FALSE);
+ g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("row_inserted", G_OBJECT_TYPE (obj)),
+ 0,
+ g_cclosure_new (G_CALLBACK (_notify_table_row_inserted),
+ NULL, NULL),
+ FALSE);
+ g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("column_deleted", G_OBJECT_TYPE (obj)),
+ 0,
+ g_cclosure_new (G_CALLBACK (_notify_table_column_deleted),
+ NULL, NULL),
+ FALSE);
+ g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("row_deleted", G_OBJECT_TYPE (obj)),
+ 0,
+ g_cclosure_new (G_CALLBACK (_notify_table_row_deleted),
+ NULL, NULL),
+ FALSE);
+ g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("column_reordered", G_OBJECT_TYPE (obj)),
+ 0,
+ g_cclosure_new (G_CALLBACK (_notify_table_column_reordered),
+ NULL, NULL),
+ FALSE);
+ g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("row_reordered", G_OBJECT_TYPE (obj)),
+ 0,
+ g_cclosure_new (G_CALLBACK (_notify_table_row_reordered),
+ NULL, NULL),
+ FALSE);
+ g_signal_connect_closure (obj, "children_changed::add",
+ g_cclosure_new (G_CALLBACK (_notify_table_child_added),
+ NULL, NULL),
+ FALSE);
+
+ g_signal_connect_closure (obj, "children_changed::remove",
+ g_cclosure_new (G_CALLBACK (_notify_table_child_removed),
+ NULL, NULL),
+ FALSE);
+
+ }
+ g_table = ATK_TABLE(obj);
+
+ atk_object_connect_property_change_handler (obj,
+ (AtkPropertyChangeHandler*) _property_change_handler);
+
+ current_obj = obj;
+ /*
+ * The use of ¤t_obj allows us to change the object being processed
+ * in the GUI.
+ */
+ if (g_visibleGUI != 1)
+ test_choice_gui(¤t_obj);
+ else if (no_gui != NULL)
+ nogui_runtest(obj);
+}
+
+static
+void other_runtest(AtkObject *obj)
+{
+ AtkObject *header_obj;
+ AtkObject *out_obj;
+ G_CONST_RETURN gchar *out_string;
+ GString *out_desc;
+ gint n_cols, n_rows;
+ gint rows_to_loop = NUM_ROWS_TO_LOOP;
+ gint i, j;
+ out_desc = g_string_sized_new(256);
+
+ n_cols = atk_table_get_n_columns(ATK_TABLE(obj));
+ n_rows = atk_table_get_n_rows(ATK_TABLE(obj));
+
+ g_print ("Number of columns is %d\n", n_cols);
+ g_print ("Number of rows is %d\n", n_rows);
+
+ /* Loop NUM_ROWS_TO_LOOP rows if possible */
+ if (n_rows < NUM_ROWS_TO_LOOP)
+ rows_to_loop = n_rows;
+
+ g_print ("\n");
+
+ /* Caption */
+
+ out_obj = atk_table_get_caption(ATK_TABLE(obj));
+ if (out_obj != NULL)
+ {
+ out_string = atk_object_get_name (out_obj);
+ if (out_string)
+ g_print("Caption Name is <%s>\n", out_string);
+ else
+ g_print("Caption has no name\n");
+ }
+ else
+ g_print("No caption\n");
+
+ /* Column descriptions and headers */
+
+ g_print ("\n");
+ for (i=0; i < n_cols; i++)
+ {
+ /* check default */
+ out_string = atk_table_get_column_description(ATK_TABLE(obj), i);
+ if (out_string != NULL)
+ g_print("%d: Column description is <%s>\n", i, out_string);
+ else
+ g_print("%d: Column description is <NULL>\n", i);
+
+ /* check setting a new value */
+
+ g_string_printf(out_desc, "new column description %d", i);
+
+ if (out_string == NULL || strcmp (out_string, out_desc->str) != 0)
+ {
+ g_print("%d, Setting the column description to <%s>\n",
+ i, out_desc->str);
+ atk_table_set_column_description(ATK_TABLE(obj), i, out_desc->str);
+ out_string = atk_table_get_column_description(ATK_TABLE(obj), i);
+ if (out_string != NULL)
+ g_print("%d: Column description is <%s>\n", i, out_string);
+ else
+ g_print("%d: Column description is <NULL>\n", i);
+ }
+
+ /* Column header */
+ header_obj = atk_table_get_column_header(ATK_TABLE(obj), i);
+ _display_header_info("Column", header_obj, i);
+ }
+
+ /* Row description */
+
+ g_print ("\n");
+
+ for (i=0; i < rows_to_loop; i++)
+ {
+ out_string = atk_table_get_row_description(ATK_TABLE(obj), i);
+ if (out_string != NULL)
+ g_print("%d: Row description is <%s>\n", i, out_string);
+ else
+ g_print("%d: Row description is <NULL>\n", i);
+
+ g_string_printf(out_desc, "new row description %d", i);
+
+ if (out_string == NULL || strcmp (out_string, out_desc->str) != 0)
+ {
+ g_print("%d: Setting the row description to <%s>\n",
+ i, out_desc->str);
+ atk_table_set_row_description(ATK_TABLE(obj), i, out_desc->str);
+
+ out_string = atk_table_get_row_description(ATK_TABLE(obj), i);
+ if (out_string != NULL)
+ g_print("%d: Row description is <%s>\n", i, out_string);
+ else
+ g_print("%d: Row description is <NULL>\n", i);
+ }
+
+ header_obj = atk_table_get_row_header(ATK_TABLE(obj), i);
+ _display_header_info("Row", header_obj, i);
+
+ for (j=0; j <n_cols; j++)
+ {
+ gint index = atk_table_get_index_at(ATK_TABLE(obj), i, j);
+ gint row, column;
+
+ column = atk_table_get_column_at_index (ATK_TABLE (obj), index);
+ g_return_if_fail (column == j);
+
+ row = atk_table_get_row_at_index (ATK_TABLE (obj), index);
+ g_return_if_fail (row == i);
+
+ if(atk_selection_is_child_selected(ATK_SELECTION(obj), index))
+ g_print("atk_selection_is_child_selected,index = %d returns TRUE\n", index);
+ /* Generic cell tests */
+ /* Just test setting column headers once. */
+
+ if (!tested_set_headers)
+ {
+ tested_set_headers = TRUE;
+
+ /* Hardcode to 1,1 for now */
+ g_print(
+ "Testing set_column_header for column %d, to table\n",
+ (n_cols - 1));
+ atk_table_set_column_header(ATK_TABLE(obj), (n_cols - 1), obj);
+
+ g_print("Testing set_row_header for row %d, to table\n", n_rows);
+ atk_table_set_row_header(ATK_TABLE(obj), n_rows, obj);
+ }
+ }
+ }
+
+ /* row/column extents */
+
+ g_print("\n");
+ g_print("Row extents at 1,1 is %d\n",
+ atk_table_get_row_extent_at(ATK_TABLE(obj), 1, 1));
+ g_print("Column extents at 1,1 is %d\n",
+ atk_table_get_column_extent_at(ATK_TABLE(obj), 1, 1));
+}
+
+static
+void ref_accessible_child_runtest(AtkObject *obj, gint child)
+{
+ AtkObject *child_obj;
+ /* ref_child */
+ g_print ("Accessing child %d\n", child);
+ child_obj = atk_object_ref_accessible_child (obj, child);
+ _property_signal_connect(child_obj);
+ if (child_obj != NULL)
+ _process_child(child_obj);
+}
+
+static
+void ref_selection_runtest (AtkObject *obj, gint index)
+{
+ AtkObject *child_obj;
+
+ /* use atk_selection_ref_selection just once to check it works */
+ child_obj = atk_selection_ref_selection(ATK_SELECTION(obj), index);
+ if (child_obj)
+ {
+ g_print("child_obj gotten from atk_selection_ref_selection\n");
+ g_object_unref (child_obj);
+ }
+ else
+ g_print("NULL returned by atk_selection_ref_selection\n");
+
+ _selection_tests(obj);
+}
+
+static
+void ref_at_runtest(AtkObject *obj, gint row, gint col)
+{
+ AtkObject *child_obj;
+ /* ref_at */
+
+ g_print("Testing ref_at row %d column %d\n", row, col);
+
+ child_obj = atk_table_ref_at(ATK_TABLE(obj), row, col);
+ _property_signal_connect(child_obj);
+
+ g_print("Row is %d, col is %d\n", row, col);
+
+ _process_child(child_obj);
+ if (child_obj)
+ g_object_unref (child_obj);
+}
+
+/**
+ * process_child
+ **/
+static void
+_process_child(AtkObject *child_obj)
+{
+ if (child_obj != NULL)
+ {
+ if (ATK_IS_TEXT(child_obj))
+ {
+ add_handlers(child_obj);
+ setup_gui(child_obj, runtest);
+ }
+ else
+ {
+ g_print("Interface is not text!\n");
+ }
+/*
+ if (ATK_IS_ACTION(child_obj))
+ {
+ gint i, j;
+ gchar *action_name;
+ gchar *action_description;
+ gchar *action_keybinding;
+ AtkAction *action = ATK_ACTION(child_obj);
+
+ i = atk_action_get_n_actions (action);
+ g_print ("Supports AtkAction with %d actions.\n", i);
+ for (j = 0; j < i; j++)
+ {
+ g_print ("Action %d:\n", j);
+ action_name = atk_action_get_name (action, j);
+ if (action_name)
+ g_print (" Name = %s\n", action_name);
+ action_description = atk_action_get_description (action, j);
+ if (action_description)
+ g_print (" Description = %s\n", action_description);
+ action_keybinding = atk_action_get_keybinding (action, j);
+ if (action_keybinding)
+ g_print (" Keybinding = %s\n", action_keybinding);
+ action_description = "new description";
+ g_print (" Setting description to %s\n", action_description);
+ atk_action_set_description (action, j, action_description);
+ action_description = atk_action_get_description (action, j);
+ if (action_description)
+ g_print (" New description is now %s\n", action_description);
+ }
+ }
+*/
+ }
+ else
+ {
+ g_print("Child is NULL!\n");
+ }
+}
+
+/**
+ * Combined tests on AtkTable and AtkSelection on individual rows rather than
+ * all of them
+ **/
+static void
+_selection_tests(AtkObject *obj)
+{
+ gint n_rows = 0;
+ gint n_cols = 0;
+ gint selection_count = 0;
+ gint i = 0;
+ gint *selected = NULL;
+ AtkTable *table;
+
+ table = ATK_TABLE (obj);
+
+ n_rows = atk_table_get_selected_rows(table, &selected);
+ for (i = 0; i < n_rows; i++)
+ {
+ g_print("atk_table_get_selected_row returns : %d\n",
+ selected[i]);
+ if (!atk_table_is_row_selected (table, selected[i]))
+ g_print("atk_table_is_row_selected returns false for selected row %d\n",
+ selected[i]);
+ }
+ g_free (selected);
+
+ selected = NULL;
+ n_cols = atk_table_get_selected_columns(table, &selected);
+ for (i = 0; i < n_cols; i++)
+ g_print("atk_table_get_selected_columns returns : %d\n", selected[i]);
+ g_free (selected);
+
+ selection_count = atk_selection_get_selection_count(ATK_SELECTION(obj));
+ g_print("atk_selection_get_selection_count returns %d\n", selection_count);
+
+ if (atk_table_is_row_selected(table, 2))
+ {
+ g_print("atk_table_is_row_selected (table, 2) returns TRUE\n");
+ atk_selection_clear_selection (ATK_SELECTION (obj));
+ if (atk_table_add_row_selection(table, 4))
+ g_print("atk_table_add_row_selection: selected row 4\n");
+ if (!atk_table_is_row_selected (table, 4))
+ g_print("atk_table_is_row_selected returns false for row 2\n");
+ if (atk_table_is_row_selected (table, 2))
+ g_print("atk_table_is_row_selected gives false positive for row 2\n");
+ }
+
+ if (atk_table_is_row_selected(table, 3))
+ {
+ if (atk_table_remove_row_selection(table, 3))
+ g_print("atk_table_remove_row_selection unselected row 3\n");
+ }
+
+ if (atk_table_is_selected(table, 5, 4))
+ {
+ atk_selection_clear_selection(ATK_SELECTION(obj));
+ g_print("atk_selection_clear_selection: just cleared all selected\n");
+ }
+
+ if (atk_table_is_column_selected(table, 2))
+ {
+ g_print("atk_table_is_column_selected(obj, 2) returns TRUE\n");
+ if (atk_table_add_column_selection(table, 4))
+ g_print("atk_table_add_column_selection: selected column 4\n");
+ g_print("atk_table_is_column_selected(obj, 2) returns TRUE\n");
+ }
+
+ if (atk_table_is_column_selected(table, 3))
+ {
+ if (atk_table_remove_column_selection(table, 3))
+ g_print("atk_table_remove_column_selection: unselected column 3\n");
+ }
+}
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_check_table);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("TestTable Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
+
+static void
+_notify_table_row_inserted (GObject *obj, gint start_offset, gint length)
+{
+ g_print ("SIGNAL - Row inserted at position %d, num of rows inserted %d!\n",
+ start_offset, length);
+}
+
+static void
+_notify_table_column_inserted (GObject *obj, gint start_offset, gint length)
+{
+ g_print ("SIGNAL - Column inserted at position %d, num of columns inserted %d!\n",
+ start_offset, length);
+}
+
+static void
+_notify_table_row_deleted (GObject *obj, gint start_offset, gint length)
+{
+ g_print ("SIGNAL - Row deleted at position %d, num of rows deleted %d!\n",
+ start_offset, length);
+}
+
+static void
+_notify_table_column_deleted (GObject *obj, gint start_offset, gint length)
+{
+ g_print ("SIGNAL - Column deleted at position %d, num of columns deleted %d!\n",
+ start_offset, length);
+}
+
+static void
+_notify_table_row_reordered (GObject *obj)
+{
+ g_print ("SIGNAL - Row reordered!\n");
+}
+
+static void
+_notify_table_column_reordered (GObject *obj)
+{
+ g_print ("SIGNAL - Column reordered!\n");
+}
+
+static void _notify_table_child_added (GObject *obj,
+ gint index, AtkObject *child)
+{
+ g_print ("SIGNAL - Child added - index %d\n", index);
+}
+
+static void _notify_table_child_removed (GObject *obj,
+ gint index, AtkObject *child)
+{
+ g_print ("SIGNAL - Child removed - index %d\n", index);
+}
+
+static void
+_display_header_info(gchar *type, AtkObject *header_obj, gint header_num)
+{
+ if (header_obj != NULL)
+ {
+ AtkRole role;
+ role = atk_object_get_role(header_obj);
+
+ if (role == ATK_ROLE_PUSH_BUTTON)
+ {
+ g_print ("%d: %s header is a push button!\n", header_num, type);
+ }
+ else if (role == ATK_ROLE_LABEL)
+ {
+ g_print ("%d: %s header is a label!\n", header_num, type);
+ }
+ else if (ATK_IS_TEXT(header_obj))
+ {
+ gchar *header_text;
+
+ header_text = atk_text_get_text (ATK_TEXT (header_obj), 0, 3);
+ if (header_text != NULL)
+ {
+ g_print("%d: %s header is a text value <%s>\n", header_num,
+ type, header_text);
+ }
+ else
+ {
+ g_print("%d: %s header is a text value <NULL>\n", header_num,
+ type);
+ }
+ }
+ else
+ {
+ g_print ("%d: %s header is of type %s!\n", header_num,
+ type, atk_role_get_name (role));
+ }
+ }
+ else
+ {
+ g_print ("%d: %s header object is NULL!\n", header_num, type);
+ }
+}
+
+static void _property_signal_connect (AtkObject *obj)
+{
+ if (g_properties && obj != NULL)
+ {
+ g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("property_change", G_OBJECT_TYPE (obj)),
+ 0,
+ g_cclosure_new (G_CALLBACK (_property_change_handler),
+ NULL, NULL),
+ FALSE);
+ }
+}
+
+static void
+_property_change_handler (AtkObject *obj,
+ AtkPropertyValues *values)
+{
+ gchar *obj_text;
+ const gchar *name;
+
+ if (g_table != NULL)
+ {
+ gint index = atk_object_get_index_in_parent(obj);
+
+ if (index >= 0)
+ g_print("Index is %d, row is %d, col is %d\n", index,
+ atk_table_get_row_at_index(g_table, index),
+ atk_table_get_column_at_index(g_table, index));
+ else
+ g_print ("index: %d for %s\n", index, g_type_name (G_OBJECT_TYPE (obj)));
+ }
+
+ if (ATK_IS_TEXT(obj))
+ {
+ obj_text = atk_text_get_text (ATK_TEXT (obj), 0, 15);
+ if (obj_text == NULL)
+ g_print(" Cell text is <NULL>\n");
+ else
+ g_print(" Cell text is <%s>\n", obj_text);
+ }
+
+ g_print(" PropertyName <%s>\n",
+ values->property_name ? values->property_name: "NULL");
+ g_print(" - ");
+
+ if (&values->old_value != NULL && G_IS_VALUE (&values->old_value))
+ {
+ GType old_type = G_VALUE_TYPE (&values->old_value);
+
+ switch (old_type)
+ {
+ case G_TYPE_INT:
+ g_print("value was <%d>\n", g_value_get_int (&values->old_value));
+ break;
+ case G_TYPE_STRING:
+ name = g_value_get_string (&values->old_value);
+ if (name != NULL)
+ g_print ("value was <%s>\n", name);
+ else
+ g_print ("value was <NULL>\n");
+ break;
+ default:
+ g_print("value was <unknown type>\n");
+ break;
+ }
+ }
+ else
+ {
+ g_print("value was <not a value>\n");
+ }
+ g_print(" - ");
+ if (&values->new_value != NULL && G_IS_VALUE (&values->new_value))
+ {
+ GType new_type = G_VALUE_TYPE (&values->new_value);
+
+ switch (new_type)
+ {
+ case G_TYPE_INT:
+ g_print("value is <%d>\n", g_value_get_int (&values->new_value));
+ break;
+ case G_TYPE_STRING:
+ name = g_value_get_string (&values->new_value);
+ if (name != NULL)
+ g_print ("value is <%s>\n", name);
+ else
+ g_print ("value is <NULL>\n");
+ break;
+ default:
+ g_print("value is <unknown type>\n");
+ break;
+ }
+ }
+ else
+ {
+ g_print("value is <not a value>\n");
+ }
+}
+
+static
+void test_choice_gui(AtkObject **obj)
+{
+ GtkWidget *window;
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+ GtkWidget *child_label;
+ GtkWidget *row_label;
+ GtkWidget *col_label;
+ GtkWidget *index_label;
+ GtkWidget *hseparator;
+ GtkWidget *hbuttonbox;
+ GtkWidget *button;
+
+
+ tc = (TestChoice *) g_malloc (sizeof(TestChoice));
+
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title(GTK_WINDOW(window), "Test to run");
+
+ g_signal_connect(GTK_OBJECT(window), "destroy",
+ GTK_SIGNAL_FUNC(destroy), &window);
+
+ vbox = gtk_vbox_new(TRUE, 0);
+ gtk_box_set_spacing(GTK_BOX(vbox), 10);
+
+
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_box_set_spacing(GTK_BOX(hbox), 10);
+ tc->tb_ref_selection = gtk_toggle_button_new_with_label("ref_selection");
+ gtk_box_pack_start_defaults(GTK_BOX(hbox), tc->tb_ref_selection);
+ index_label = gtk_label_new("index: ");
+ gtk_box_pack_start_defaults(GTK_BOX(hbox), index_label);
+ tc->index_entry = gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(tc->index_entry), "1");
+ gtk_box_pack_start_defaults(GTK_BOX(hbox), tc->index_entry);
+ gtk_box_pack_start_defaults(GTK_BOX(vbox), hbox);
+
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_box_set_spacing(GTK_BOX(hbox), 10);
+ tc->tb_ref_at = gtk_toggle_button_new_with_label("ref_at");
+ gtk_box_pack_start_defaults(GTK_BOX(hbox), tc->tb_ref_at);
+ row_label = gtk_label_new("row:");
+ gtk_box_pack_start_defaults(GTK_BOX(hbox), row_label);
+ tc->row_entry = gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(tc->row_entry), "1");
+ gtk_box_pack_start_defaults(GTK_BOX(hbox), tc->row_entry);
+ col_label = gtk_label_new("column:");
+ gtk_box_pack_start_defaults(GTK_BOX(hbox), col_label);
+ tc->col_entry = gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(tc->col_entry), "1");
+ gtk_box_pack_start_defaults(GTK_BOX(hbox), tc->col_entry);
+ gtk_box_pack_start_defaults(GTK_BOX(vbox), hbox);
+
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_box_set_spacing(GTK_BOX(hbox), 10);
+ tc->tb_ref_accessible_child = gtk_toggle_button_new_with_label("ref_accessible_child");
+ gtk_box_pack_start_defaults(GTK_BOX(hbox), tc->tb_ref_accessible_child);
+ child_label = gtk_label_new("Child no:");
+ gtk_box_pack_start_defaults(GTK_BOX(hbox), child_label);
+ tc->child_entry = gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(tc->child_entry), "1");
+ gtk_box_pack_start_defaults(GTK_BOX(hbox), tc->child_entry);
+ gtk_box_pack_start_defaults(GTK_BOX(vbox), hbox);
+
+ tc->tb_others = gtk_toggle_button_new_with_label("others");
+ gtk_box_pack_start_defaults(GTK_BOX(vbox), tc->tb_others);
+
+ hseparator = gtk_hseparator_new();
+ gtk_box_pack_start_defaults(GTK_BOX(vbox), hseparator);
+
+ button = gtk_button_new_with_mnemonic("_Run Test");
+
+ hbuttonbox = gtk_hbutton_box_new();
+ gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox),
+ GTK_BUTTONBOX_SPREAD);
+ gtk_box_pack_end_defaults(GTK_BOX(hbuttonbox), GTK_WIDGET(button));
+ gtk_box_pack_end_defaults(GTK_BOX(vbox), hbuttonbox);
+ g_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(choicecb), obj);
+
+ gtk_container_add(GTK_CONTAINER(window), vbox);
+ gtk_widget_show(vbox);
+ gtk_widget_show(window);
+ gtk_widget_show_all(GTK_WIDGET(window));
+
+ g_visibleGUI = 1;
+}
+
+void static
+nogui_runtest (AtkObject *obj)
+{
+ g_print ("Running non-GUI tests...\n");
+ other_runtest (obj);
+ nogui_ref_at_runtest (obj);
+}
+
+static void
+nogui_ref_at_runtest (AtkObject *obj)
+{
+ AtkObject *child_obj;
+ gint i, j;
+ gint n_cols;
+ gint rows_to_loop = 5;
+
+ n_cols = atk_table_get_n_columns (ATK_TABLE(obj));
+
+ if (atk_table_get_n_rows(ATK_TABLE(obj)) < rows_to_loop)
+ rows_to_loop = atk_table_get_n_rows (ATK_TABLE(obj));
+
+ for (i=0; i < rows_to_loop; i++)
+ {
+ /* Just the first rows_to_loop rows */
+ for (j=0; j < n_cols; j++)
+ {
+ gint index = atk_table_get_index_at(ATK_TABLE(obj), i, j);
+ if(atk_selection_is_child_selected(ATK_SELECTION(obj), index))
+ g_print("atk_selection_is_child_selected,index = %d returns TRUE\n", index);
+
+ g_print("Testing ref_at row %d column %d\n", i, j);
+
+ if (i == 3 && j == 0)
+ {
+ g_print("child_obj gotten from atk_selection_ref_selection\n");
+
+ /* use atk_selection_ref_selection just once to check it works */
+ child_obj = atk_selection_ref_selection(ATK_SELECTION(obj), index );
+ }
+ else
+ {
+ child_obj = atk_table_ref_at(ATK_TABLE(obj), i, j);
+ }
+
+ _property_signal_connect(child_obj);
+
+ g_print("Index is %d, row is %d, col is %d\n", index,
+ atk_table_get_row_at_index(ATK_TABLE(obj), index),
+ atk_table_get_column_at_index(ATK_TABLE(obj), index));
+
+ nogui_process_child (child_obj);
+
+ /* Generic cell tests */
+ /* Just test setting column headers once. */
+
+ if (!tested_set_headers)
+ {
+ tested_set_headers = TRUE;
+
+ g_print("Testing set_column_header for column %d, to cell value %d,%d\n",
+ j, i, j);
+ atk_table_set_column_header(ATK_TABLE(obj), j, child_obj);
+
+ g_print("Testing set_row_header for row %d, to cell value %d,%d\n",
+ i, i, j);
+ atk_table_set_row_header(ATK_TABLE(obj), i, child_obj);
+ }
+ if (child_obj)
+ g_object_unref (child_obj);
+ }
+ }
+}
+
+static void
+nogui_process_child (AtkObject *obj)
+{
+ gchar default_val[5] = "NULL";
+
+ if (ATK_IS_TEXT(obj))
+ {
+ gchar *current_text;
+ current_text = atk_text_get_text (ATK_TEXT(obj), 0, -1);
+ g_print ("Child supports text interface.\nCurrent text is %s\n", current_text);
+ }
+
+ if (ATK_IS_ACTION(obj))
+ {
+ AtkAction *action = ATK_ACTION(obj);
+ gint n_actions, i;
+ G_CONST_RETURN gchar *name, *description;
+
+ n_actions = atk_action_get_n_actions (action);
+ g_print ("Child supports %d actions.\n", n_actions);
+ for (i = 0; i < n_actions; i++)
+ {
+ name = atk_action_get_name (action, i);
+ description = atk_action_get_description (action, i);
+
+ if (name == NULL)
+ name = default_val;
+ if (description == NULL)
+ description = default_val;
+
+ g_print (" %d: name = <%s>\n", i, name);
+ g_print (" description = <%s>\n", description);
+ }
+ }
+}
+
--- /dev/null
+#include <atk/atkeditabletext.h>
+#include "testtextlib.h"
+
+#define NUM_VALID_ROLES 6
+
+static void _create_event_watcher (void);
+static void _check_text (AtkObject *obj);
+void runtest(AtkObject *, gint);
+
+static guint id1 = 0;
+static guint win_count = 0;
+
+static void _check_text (AtkObject *in_obj)
+{
+ AtkObject *obj = NULL;
+ AtkRole role;
+ gchar* title;
+ AtkRole valid_roles[NUM_VALID_ROLES];
+
+ if (g_getenv("TEST_ACCESSIBLE_DELAY") != NULL)
+ {
+ int max_cnt = string_to_int(g_getenv("TEST_ACCESSIBLE_DELAY"));
+ win_count++;
+ if (win_count <= max_cnt)
+ return;
+ }
+
+ /* Set Up */
+
+ valid_roles[0] = ATK_ROLE_TEXT;
+ valid_roles[1] = ATK_ROLE_LABEL;
+ valid_roles[2] = ATK_ROLE_ACCEL_LABEL;
+ valid_roles[3] = ATK_ROLE_PASSWORD_TEXT;
+ valid_roles[4] = ATK_ROLE_TABLE_CELL;
+ valid_roles[5] = ATK_ROLE_PANEL;
+
+ /* The following if/else grabs the windows name, or sets title to NULL if none. */
+ if (in_obj->name)
+ {
+ title = in_obj->name;
+ }
+ else
+ {
+ GtkWidget *toplevel;
+ GtkWidget* widget = GTK_ACCESSIBLE (in_obj)->widget;
+
+ if (widget == NULL)
+ {
+ title = NULL;
+ }
+
+ toplevel = gtk_widget_get_toplevel (widget);
+ if (GTK_IS_WINDOW (toplevel) && GTK_WINDOW (toplevel)->title)
+ {
+ title = GTK_WINDOW (toplevel)->title;
+ }
+ else
+ title = NULL;
+ }
+ /* If no window name, do nothing */
+ if (title == NULL)
+ return;
+ /*
+ * If testtext test program, find obj just by role since only one child
+ * with no name
+ */
+ else if (g_ascii_strncasecmp(title, "testtext", 7) == 0)
+ {
+ obj = find_object_by_role(in_obj, valid_roles, NUM_VALID_ROLES);
+ }
+ /*
+ * Otherwise, get obj by name and role so you can specify exactly which
+ * obj to run tests on
+ */
+ else
+ {
+ G_CONST_RETURN gchar *test_accessible_name = g_getenv ("TEST_ACCESSIBLE_NAME");
+
+ if (test_accessible_name != NULL)
+ {
+ obj = find_object_by_accessible_name_and_role(in_obj,
+ test_accessible_name, valid_roles, NUM_VALID_ROLES);
+ }
+ if (obj != NULL)
+ {
+ if (atk_object_get_role (obj) == ATK_ROLE_PANEL)
+ {
+ /* Get the child and check whether it is a label */
+
+ obj = atk_object_ref_accessible_child (obj, 0);
+ g_assert (atk_object_get_role (obj) == ATK_ROLE_LABEL);
+ g_object_unref (obj);
+ }
+ g_print("Found valid name and role in child!\n");
+ }
+ else
+ {
+ obj = find_object_by_role(in_obj, valid_roles, NUM_VALID_ROLES - 1);
+ if (obj != NULL)
+ g_print("Found valid role in child\n");
+ }
+ }
+ if (obj == NULL)
+ {
+ g_print("Object not found\n");
+ return;
+ }
+ role = atk_object_get_role(obj);
+
+ g_print("_check_text - Found role type %s!\n\n", atk_role_get_name (role));
+
+ add_handlers(obj);
+
+ if (!(isVisibleDialog()))
+ setup_gui(obj, runtest);
+ atk_remove_focus_tracker (id1);
+}
+
+static void
+_create_event_watcher (void)
+{
+ id1 = atk_add_focus_tracker (_check_text);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testtext Module loaded.\n");
+ _create_event_watcher();
+
+ return 0;
+}
+
+
--- /dev/null
+#include <string.h>
+#include <stdio.h>
+#include "testtextlib.h"
+
+static AtkAttributeSet *attrib = NULL;
+static char result_string[2][6] = {"FALSE", "TRUE"};
+
+/**
+ * setup_gui:
+ * @obj: An @AtkObject
+ * @test: The callback to be run when the "Run Tests" button
+ * in the GUI is clicked.
+ *
+ * Sets up the GUI windows.
+ *
+ * Returns: the window number, or -1 if failure.
+ **/
+gint setup_gui(AtkObject *obj, TLruntest test)
+{
+ gchar *paramnames[MAX_PARAMS];
+ gchar *defaults[MAX_PARAMS];
+ static OutputWindow *tow = NULL;
+ gint window;
+
+ if (tow)
+ window = create_windows(obj, test, &tow);
+ else
+ window = create_windows(obj, test, &tow);
+
+ if (window == -1)
+ return -1;
+
+ /* Get Text [at|after|before] Offset Tests */
+ paramnames[0] = "offset";
+ defaults[0] = "1";
+ add_test(window, "atk_text_get_text_after_offset", 1, paramnames, defaults);
+ add_test(window, "atk_text_get_text_before_offset", 1, paramnames, defaults);
+ add_test(window, "atk_text_get_text_at_offset",1 , paramnames, defaults);
+
+ /* Get Character Count Test */
+ add_test(window, "atk_text_get_character_count", 0, NULL, NULL);
+
+ /* Get Character At Offset Test */
+ paramnames[0] = "offset";
+ defaults[0] = "1";
+ add_test(window, "atk_text_get_character_at_offset", 1, paramnames, defaults);
+
+ /* Get Text Test */
+ paramnames[0] = "position 1";
+ paramnames[1] = "position 2";
+ defaults[0] = "0";
+ defaults[1] = "5";
+ add_test(window, "atk_text_get_text", 2, paramnames, defaults);
+
+ /* Caret Tests */
+ add_test(window, "atk_text_get_caret_offset", 0, NULL, NULL);
+
+ paramnames[0] = "offset";
+ defaults[0] = "1";
+ add_test(window, "atk_text_set_caret_offset", 1, paramnames, defaults);
+
+ /* Selection Tests */
+ add_test(window, "atk_text_get_n_selections", 0, NULL, NULL);
+
+ paramnames[0] = "selection no";
+ defaults[0] = "0";
+ add_test(window, "atk_text_get_selection", 1, paramnames, defaults);
+
+ paramnames[0] = "start";
+ paramnames[1] = "end";
+ defaults[0] = "3";
+ defaults[1] = "8";
+ add_test(window, "atk_text_add_selection", 2, paramnames, defaults);
+
+ paramnames[0] = "selection no";
+ paramnames[1] = "start";
+ paramnames[2] = "end";
+ defaults[0] = "0";
+ defaults[1] = "5";
+ defaults[2] = "7";
+ add_test(window, "atk_text_set_selection", 3, paramnames, defaults);
+
+ paramnames[0] = "selection no";
+ defaults[0] = "0";
+ add_test(window, "atk_text_remove_selection", 1, paramnames, defaults);
+
+ paramnames[0] = "offset";
+ defaults[0] = "36";
+ add_test(window, "atk_text_get_run_attributes", 1, paramnames, defaults);
+
+ add_test(window, "atk_text_get_default_attributes", 0, paramnames, defaults);
+
+ paramnames[0] = "offset";
+ paramnames[1] = "coord mode";
+ defaults[0] = "0";
+ defaults[1] = "ATK_XY_SCREEN";
+ add_test(window, "atk_text_get_character_extents", 2, paramnames, defaults);
+
+ paramnames[0] = "x";
+ paramnames[1] = "y";
+ paramnames[2] = "coord mode";
+ defaults[0] = "106";
+ defaults[1] = "208";
+ defaults[2] = "ATK_XY_SCREEN";
+ add_test(window, "atk_text_get_offset_at_point", 3, paramnames, defaults);
+
+ /* Editable Text Tests */
+ if (ATK_IS_EDITABLE_TEXT(obj))
+ {
+
+ paramnames[0] = "start";
+ paramnames[1] = "end";
+ defaults[0] = "20";
+ defaults[1] = "27";
+ add_test(window, "atk_editable_text_set_run_attributes", 2, paramnames, defaults);
+
+ paramnames[0] = "start";
+ paramnames[1] = "end";
+ defaults[0] = "3";
+ defaults[1] = "5";
+ add_test(window, "atk_editable_text_cut_text", 2, paramnames, defaults);
+
+ paramnames[0] = "position";
+ defaults[0] = "8";
+ add_test(window, "atk_editable_text_paste_text", 1, paramnames, defaults);
+
+ paramnames[0] = "start";
+ paramnames[1] = "end";
+ defaults[0] = "15";
+ defaults[1] = "20";
+ add_test(window, "atk_editable_text_delete_text", 2, paramnames, defaults);
+ paramnames[0] = "start";
+ paramnames[1] = "end";
+ defaults[0] = "5";
+ defaults[1] = "20";
+ add_test(window, "atk_editable_text_copy_text", 2, paramnames, defaults);
+
+ paramnames[0] = "insert text";
+ paramnames[1] = "position";
+ defaults[0] = "this is my insert";
+ defaults[1] = "15";
+ add_test(window, "atk_editable_text_insert_text", 2, paramnames, defaults);
+ }
+ return window;
+}
+
+/**
+ * add_handlers:
+ * @obj: An #AtkObject
+ *
+ * Sets up text signal handlers.
+ *
+ **/
+void add_handlers(AtkObject *obj)
+{
+ if (!already_accessed_atk_object(obj))
+ {
+ /* Set up signal handlers */
+
+ g_print ("Adding signal handler\n");
+ g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("text_caret_moved", G_OBJECT_TYPE (obj)),
+ 0,
+ g_cclosure_new (G_CALLBACK (_notify_caret_handler),
+ NULL, NULL),
+ FALSE);
+
+ g_signal_connect_closure (obj, "text_changed::insert",
+ g_cclosure_new (G_CALLBACK (_notify_text_insert_handler),
+ NULL, NULL),
+ FALSE);
+
+ g_signal_connect_closure (obj, "text_changed::delete",
+ g_cclosure_new (G_CALLBACK (_notify_text_delete_handler),
+ NULL, NULL),
+ FALSE);
+ }
+}
+
+/**
+ * notify_text_insert_handler:
+ * @obj: A #Gobject
+ * @start_offset: Start offset of insert
+ * @end_offset: End offset of insert.
+ *
+ * Text inserted singal handler
+ **/
+void
+_notify_text_insert_handler (GObject *obj, int start_offset, int end_offset)
+{
+ g_print ("SIGNAL - Text inserted at position %d, length %d!\n",
+ start_offset, end_offset);
+}
+
+/**
+ * notify_text_delete_handler:
+ * @obj: A #Gobject
+ * @start_offset: Start offset of delete
+ * @end_offset: End offset of delete.
+ *
+ * Text deleted singal handler
+ **/
+void
+_notify_text_delete_handler (GObject *obj, int start_offset, int end_offset)
+{
+ g_print ("SIGNAL - Text deleted at position %d, length %d!\n",
+ start_offset, end_offset);
+}
+
+/**
+ * notify_caret_handler:
+ * @obj: A #Gobject
+ * @position: Caret position
+ *
+ * Caret (cursor) moved signal handler.
+ **/
+void
+_notify_caret_handler (GObject *obj, int position)
+{
+ g_print ("SIGNAL - The caret moved to position %d!\n", position);
+}
+
+/**
+ * runtest:
+ * @obj: An #AtkObject
+ * @win_val: The window number
+ *
+ * The callback to run when the "Run Tests" button on the
+ * Test GUI is clicked.
+ **/
+void
+runtest(AtkObject *obj, gint win_val)
+{
+ gint i, size;
+ gunichar uni_char;
+ gchar output[MAX_LINE_SIZE];
+ gchar **testsOn;
+
+ testsOn = tests_set(win_val, &size);
+
+ for(i = 0; i < size; i++)
+ {
+ gint param_int1, param_int2, start, end, j, x, y, height, width;
+ gchar *param_string1, *param_string2, *param_string3, *text;
+ gboolean result;
+ gint index;
+
+ if (strcmp(testsOn[i], "atk_text_get_text_at_offset") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_text_get_text_at_offset", "offset");
+ param_int1 = string_to_int(param_string1);
+
+ _run_offset_test(obj, "at", param_int1, ATK_TEXT_BOUNDARY_WORD_END);
+ _run_offset_test(obj, "at", param_int1, ATK_TEXT_BOUNDARY_WORD_START);
+ _run_offset_test(obj, "at", param_int1, ATK_TEXT_BOUNDARY_LINE_END);
+ _run_offset_test(obj, "at", param_int1, ATK_TEXT_BOUNDARY_LINE_START);
+ _run_offset_test(obj, "at", param_int1, ATK_TEXT_BOUNDARY_SENTENCE_END);
+ _run_offset_test(obj, "at", param_int1, ATK_TEXT_BOUNDARY_SENTENCE_START);
+ _run_offset_test(obj, "at", param_int1, ATK_TEXT_BOUNDARY_CHAR);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_text_after_offset") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_text_get_text_after_offset", "offset");
+ param_int1 = string_to_int(param_string1);
+
+ _run_offset_test(obj, "after", param_int1, ATK_TEXT_BOUNDARY_WORD_END);
+ _run_offset_test(obj, "after", param_int1, ATK_TEXT_BOUNDARY_WORD_START);
+ _run_offset_test(obj, "after", param_int1, ATK_TEXT_BOUNDARY_LINE_END);
+ _run_offset_test(obj, "after", param_int1, ATK_TEXT_BOUNDARY_LINE_START);
+ _run_offset_test(obj, "after", param_int1, ATK_TEXT_BOUNDARY_SENTENCE_END);
+ _run_offset_test(obj, "after", param_int1, ATK_TEXT_BOUNDARY_SENTENCE_START);
+ _run_offset_test(obj, "after", param_int1, ATK_TEXT_BOUNDARY_CHAR);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_text_before_offset") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_text_get_text_before_offset", "offset");
+ param_int1 = string_to_int(param_string1);
+
+ _run_offset_test(obj, "before", param_int1, ATK_TEXT_BOUNDARY_WORD_END);
+ _run_offset_test(obj, "before", param_int1, ATK_TEXT_BOUNDARY_WORD_START);
+ _run_offset_test(obj, "before", param_int1, ATK_TEXT_BOUNDARY_LINE_END);
+ _run_offset_test(obj, "before", param_int1, ATK_TEXT_BOUNDARY_LINE_START);
+ _run_offset_test(obj, "before", param_int1, ATK_TEXT_BOUNDARY_SENTENCE_END);
+ _run_offset_test(obj, "before", param_int1, ATK_TEXT_BOUNDARY_SENTENCE_START);
+ _run_offset_test(obj, "before", param_int1, ATK_TEXT_BOUNDARY_CHAR);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_character_count") == 0)
+ {
+ param_int1 = atk_text_get_character_count (ATK_TEXT (obj));
+ sprintf(output, "\nText character count: %d\n", param_int1);
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_character_at_offset") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_text_get_character_at_offset",
+ "offset");
+ uni_char = atk_text_get_character_at_offset (ATK_TEXT(obj),
+ string_to_int(param_string1));
+ sprintf(output, "\nCharacter at offset %d: |%x|\n",
+ string_to_int(param_string1), uni_char);
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_text") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_text_get_text", "position 1");
+ param_string2 = get_arg_of_func(win_val, "atk_text_get_text", "position 2");
+ text = atk_text_get_text (ATK_TEXT (obj), string_to_int(param_string1),
+ string_to_int(param_string2));
+ sprintf(output, "\nText %d, %d: %s\n", string_to_int(param_string1),
+ string_to_int(param_string2), text);
+ g_free (text);
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_caret_offset") == 0)
+ {
+ param_int1 = atk_text_get_caret_offset (ATK_TEXT (obj));
+ if (param_int1 == -1)
+ sprintf(output, "\nCaret offset: |Not Supported|\n");
+ else
+ sprintf(output, "\nCaret offset: %d\n", param_int1);
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_set_caret_offset") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_text_set_caret_offset", "offset");
+ atk_text_set_caret_offset(ATK_TEXT(obj), string_to_int(param_string1));
+ sprintf(output, "\nPutting caret at offset: |%d|\n",
+ string_to_int(param_string1));
+ param_int1 = atk_text_get_caret_offset (ATK_TEXT (obj));
+
+ if (param_int1 == -1)
+ sprintf(output, "\nCaret offset: |Not Supported|\n");
+ else
+ sprintf(output, "\nCaret offset was set at: |%d|\n", param_int1);
+
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_n_selections") == 0)
+ {
+ param_int1 = atk_text_get_n_selections(ATK_TEXT(obj));
+ if (param_int1 == -1)
+ {
+ sprintf(output, "\nNo selected regions\n");
+ set_output_buffer(output);
+ }
+
+ for (j = 0; j < param_int1; j++)
+ {
+ sprintf(output, "\nNumber of selected text regions is: |%d|\n", j);
+ set_output_buffer(output);
+
+ text = atk_text_get_selection(ATK_TEXT(obj), j, &start, &end);
+ if (text != NULL)
+ {
+ sprintf(output, "\nSelected text for region %d is: |%s|\n", j, text);
+ set_output_buffer(output);
+ sprintf(output,
+ "\nStart selection bounds: %d\tEnd selection bounds: %d\n",
+ start, end);
+ }
+ else
+ {
+ sprintf(output, "\nNo selected region %d\n", j);
+ }
+
+ set_output_buffer(output);
+ }
+ }
+
+ if (strcmp(testsOn[i], "atk_text_add_selection") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_text_add_selection", "start");
+ param_string2 = get_arg_of_func(win_val, "atk_text_add_selection", "end");
+ result = atk_text_add_selection(ATK_TEXT(obj),
+ string_to_int(param_string1), string_to_int(param_string2));
+ sprintf(output, "\nSet selection bounds between %d, and %d: %s",
+ string_to_int(param_string1), string_to_int(param_string2),
+ result_string[result]);
+ set_output_buffer(output);
+
+ param_int1 = atk_text_get_n_selections(ATK_TEXT(obj));
+ for (j = 0; j < param_int1; j++)
+ {
+ sprintf(output, "\nNumber of selected text region is: %d\n", j);
+ set_output_buffer(output);
+ text = atk_text_get_selection(ATK_TEXT(obj), j, &start, &end);
+
+ if (text != NULL)
+ {
+ sprintf(output, "\nSelected text for region %d is: |%s|\n", j, text);
+ set_output_buffer(output);
+ sprintf(output,
+ "\nStart selection bounds: %d\tEnd selection bounds: %d\n",
+ start, end);
+ }
+ else
+ {
+ sprintf(output, "\nNo selected region %d\n", j);
+ }
+
+ set_output_buffer(output);
+ }
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_selection") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_text_get_selection", "selection no");
+ text = atk_text_get_selection(ATK_TEXT(obj),
+ string_to_int(param_string1), &start, &end);
+
+ if (text != NULL)
+ {
+ sprintf(output, "\nSelected text for region %d is: |%s|\n",
+ string_to_int(param_string1), text);
+ set_output_buffer(output);
+ sprintf(output,
+ "\nStart selection bounds: %d\t End selection bounds: %d\n",
+ start, end);
+ }
+ else
+ {
+ sprintf(output, "\nNo selected region %d\n", string_to_int(param_string1));
+ }
+
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_set_selection") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_text_set_selection", "selection no");
+ param_string2 = get_arg_of_func(win_val, "atk_text_set_selection", "start");
+ param_string3 = get_arg_of_func(win_val, "atk_text_set_selection", "end");
+ result = atk_text_set_selection(ATK_TEXT(obj), string_to_int(param_string1),
+ string_to_int(param_string2), string_to_int(param_string3));
+ sprintf(output, "Set selection %d's bounds between %d and %d: %s\n",
+ string_to_int(param_string1), string_to_int(param_string2),
+ string_to_int(param_string3), result_string[result]);
+ set_output_buffer(output);
+ text = atk_text_get_selection(ATK_TEXT(obj), string_to_int(param_string1),
+ &start, &end);
+
+ if (text != NULL)
+ {
+ sprintf(output, "Selected text for the reset region %d is: |%s|\n",
+ string_to_int(param_string1), text);
+ set_output_buffer(output);
+ sprintf(output,
+ "\nNew start selection bounds: %d\tNew end selection bounds: %d\n",
+ start, end);
+ }
+ else
+ {
+ sprintf(output, "\nNo selected region %d\n", string_to_int(param_string1));
+ }
+
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_remove_selection") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_text_remove_selection", "selection no");
+ result = atk_text_remove_selection(ATK_TEXT(obj), string_to_int(param_string1));
+ sprintf(output, "Remove selection for region %d: %s\n",
+ string_to_int(param_string1), result_string[result]);
+ set_output_buffer(output);
+ text = atk_text_get_selection(ATK_TEXT(obj),
+ string_to_int(param_string1), &start, &end);
+
+ if (text != NULL)
+ sprintf(output, "\nRemoved regions text should be empty instead of: %s", text);
+ else
+ sprintf(output, "\nRemoved regions text should be empty, this is: ||");
+
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_run_attributes") == 0)
+ {
+ gint test_int;
+ param_string1 = get_arg_of_func(win_val, "atk_text_get_run_attributes", "offset");
+ test_int = string_to_int(param_string1);
+ attrib = atk_text_get_run_attributes(ATK_TEXT(obj), test_int, &start, &end);
+ sprintf(output, "get_run_attributes at offset %i:\nStart: %i, End: %i\n", test_int,
+ start, end);
+ set_output_buffer(output);
+ if (attrib != NULL) {
+ GSList *node;
+ index = 0;
+ node = attrib;
+ while (node != NULL)
+ {
+ AtkAttribute* att = node->data;
+
+ sprintf(output, "List index: %i, Name: %s, Value: %s\n", index,
+ att->name, att->value);
+ set_output_buffer(output);
+ node = node->next;
+ index++;
+ }
+ atk_attribute_set_free (attrib);
+ }
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_default_attributes") == 0)
+ {
+ attrib = atk_text_get_default_attributes(ATK_TEXT(obj));
+ sprintf(output, "get_default_attributes\n");
+ set_output_buffer(output);
+ if (attrib != NULL) {
+ GSList *node;
+ index = 0;
+ node = attrib;
+ while (node != NULL)
+ {
+ AtkAttribute* att = node->data;
+
+ sprintf(output, "List index: %i, Name: %s, Value: %s\n", index,
+ att->name, att->value);
+ set_output_buffer(output);
+ node = node->next;
+ index++;
+ }
+ atk_attribute_set_free (attrib);
+ }
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_character_extents") == 0)
+ {
+ gint test_int;
+ param_string1 = get_arg_of_func(win_val, "atk_text_get_character_extents",
+ "offset");
+ param_string2 = get_arg_of_func(win_val, "atk_text_get_character_extents",
+ "coord mode");
+ test_int = string_to_int(param_string1);
+ if (strcmp(param_string2, "ATK_XY_SCREEN") == 0)
+ {
+ atk_text_get_character_extents(ATK_TEXT(obj), test_int, &x, &y, &width,
+ &height, ATK_XY_SCREEN);
+ sprintf(output,
+ "get_character_extents at offset %i, mode: SCREEN\nX: %i, Y: %i, width: %i, height: %i\n",
+ test_int, x, y, width, height);
+ }
+ else if (strcmp(param_string2, "ATK_XY_WINDOW") == 0)
+ {
+ atk_text_get_character_extents(ATK_TEXT(obj), test_int, &x, &y, &width,
+ &height, ATK_XY_WINDOW);
+ sprintf(output,
+ "get_character_extents at offset %i, mode: WIDGET_WINDOW\nX: %i, Y: %i, width: %i, height: %i\n",
+ test_int, x, y, width, height);
+ }
+ else
+ sprintf(output, "get_character_extents_at_offset: Invalid coord mode argument!");
+
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_offset_at_point") == 0)
+ {
+ gint test_int;
+ param_string1 = get_arg_of_func(win_val, "atk_text_get_offset_at_point", "x");
+ param_string2 = get_arg_of_func(win_val, "atk_text_get_offset_at_point", "y");
+ param_string3 = get_arg_of_func(win_val, "atk_text_get_offset_at_point", "coord mode");
+ param_int1 = string_to_int(param_string1);
+ param_int2 = string_to_int(param_string2);
+ if (strcmp(param_string3, "ATK_XY_SCREEN") == 0)
+ {
+ test_int = atk_text_get_offset_at_point(ATK_TEXT(obj), param_int1, param_int2,
+ ATK_XY_SCREEN);
+ if (test_int != -1)
+ sprintf(output, "get_offset_at_point %i,%i mode: SCREEN is %i\n", param_int1, param_int2, test_int);
+ else
+ sprintf(output, "Cannot get_offset_at_point\n");
+ }
+ else if (strcmp(param_string3, "ATK_XY_WINDOW") == 0)
+ {
+ test_int = atk_text_get_offset_at_point(ATK_TEXT(obj), param_int1, param_int2,
+ ATK_XY_WINDOW);
+ if (test_int != -1)
+ sprintf(output, "get_offset_at_point %i,%i mode: WIDGET_WINDOW is %i\n", param_int1, param_int2, test_int);
+ else
+ sprintf(output, "Cannot get_offset_at_point\n");
+ }
+ else
+ sprintf(output, "get_offset_at_point: Invalid coord mode argument!");
+
+ set_output_buffer(output);
+ }
+ if (ATK_IS_EDITABLE_TEXT(obj))
+ {
+ if (strcmp(testsOn[i], "atk_editable_text_set_run_attributes") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val,
+ "atk_editable_text_set_run_attributes", "start");
+ param_string2 = get_arg_of_func(win_val,
+ "atk_editable_text_set_run_attributes", "end");
+ result = atk_editable_text_set_run_attributes(ATK_EDITABLE_TEXT(obj),
+ attrib, string_to_int(param_string1), string_to_int(param_string2));
+ if (result)
+ sprintf(output, "\nSetting attributes in range %d to %d...OK\n",
+ string_to_int(param_string1), string_to_int(param_string2));
+ else
+ sprintf(output, "\nSetting attributes in range %d to %d...Failed\n",
+ string_to_int(param_string1), string_to_int(param_string2));
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_editable_text_cut_text") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_editable_text_cut_text", "start");
+ param_string2 = get_arg_of_func(win_val, "atk_editable_text_cut_text", "end");
+ atk_editable_text_cut_text(ATK_EDITABLE_TEXT(obj),
+ string_to_int(param_string1), string_to_int(param_string2));
+ sprintf(output, "\nCutting text %d to %d...\n",
+ string_to_int(param_string1), string_to_int(param_string2));
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_editable_text_paste_text") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_editable_text_paste_text",
+ "position");
+ atk_editable_text_paste_text(ATK_EDITABLE_TEXT(obj),
+ string_to_int(param_string1));
+ sprintf(output, "\nPasting text to %d\n", string_to_int(param_string1));
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_editable_text_delete_text") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_editable_text_delete_text", "start");
+ param_string2 = get_arg_of_func(win_val, "atk_editable_text_delete_text", "end");
+ atk_editable_text_delete_text(ATK_EDITABLE_TEXT(obj),
+ string_to_int(param_string1), string_to_int(param_string2));
+ sprintf(output, "\nDeleting text %d to %d...\n",
+ string_to_int(param_string1), string_to_int(param_string2));
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_editable_text_copy_text") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_editable_text_copy_text", "start");
+ param_string2 = get_arg_of_func(win_val, "atk_editable_text_copy_text", "end");
+ atk_editable_text_copy_text(ATK_EDITABLE_TEXT(obj),
+ string_to_int(param_string1), string_to_int(param_string2));
+ sprintf(output, "\nCopying text %d to %d...\n",
+ string_to_int(param_string1), string_to_int(param_string2));
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_editable_text_insert_text") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_editable_text_insert_text",
+ "insert text");
+ param_string2 = get_arg_of_func(win_val, "atk_editable_text_insert_text",
+ "position");
+ param_int2 = string_to_int(param_string2);
+ atk_editable_text_insert_text(ATK_EDITABLE_TEXT(obj),
+ param_string1, strlen(param_string1), ¶m_int2);
+ sprintf(output, "\nInserting text at %d...\n", param_int2);
+ set_output_buffer(output);
+ }
+ }
+ }
+}
+
+/**
+ * _run_offset_test:
+ * @obj: An #AtkObject
+ * @type: The type of test to run. Can be "at", "before", or "after".
+ * @offset: The offset into the text buffer.
+ * @boundary: The boundary type.
+ *
+ * Tests the following ATK_TEXT API functions:
+ * atk_text_get_text_at_offset
+ * atk_text_get_text_before_offseet
+ * atk_text_get_text_after_offset
+ **/
+void _run_offset_test(AtkObject * obj, char * type, gint offset,
+ AtkTextBoundary boundary)
+{
+ gchar output[MAX_LINE_SIZE];
+ gchar default_val[5] = "NULL";
+ gchar *text;
+ gint startOffset, endOffset;
+
+ if (strcmp(type, "at") == 0)
+ text = atk_text_get_text_at_offset (ATK_TEXT (obj),
+ offset, boundary, &startOffset, &endOffset);
+ else if (strcmp(type, "before") == 0)
+ text = atk_text_get_text_before_offset (ATK_TEXT (obj),
+ offset, boundary, &startOffset, &endOffset);
+ else if (strcmp(type, "after") == 0)
+ text = atk_text_get_text_after_offset (ATK_TEXT (obj),
+ offset, boundary, &startOffset, &endOffset);
+ else
+ text = NULL;
+
+ if (text == NULL)
+ text = g_strdup (default_val);
+
+ if (boundary == ATK_TEXT_BOUNDARY_CHAR)
+ sprintf(output, "\n|%s| Text |%s| Boundary |BOUNDARY_CHAR|\n",
+ type, text);
+ else if (boundary == ATK_TEXT_BOUNDARY_WORD_START)
+ sprintf(output, "\n|%s| Text |%s| Boundary |BOUNDARY_WORD_START|\n",
+ type, text);
+ else if (boundary == ATK_TEXT_BOUNDARY_WORD_END)
+ sprintf(output, "\n|%s| Text |%s| Boundary |BOUNDARY_WORD_END|\n",
+ type, text);
+ else if (boundary == ATK_TEXT_BOUNDARY_SENTENCE_START)
+ sprintf(output, "\n|%s| Text |%s| Boundary |BOUNDARY_SENTENCE_START|\n",
+ type, text);
+ else if (boundary == ATK_TEXT_BOUNDARY_SENTENCE_END)
+ sprintf(output, "\n|%s| Text |%s| Boundary |BOUNDARY_SENTENCE_END|\n",
+ type, text);
+ else if (boundary == ATK_TEXT_BOUNDARY_LINE_START)
+ sprintf(output, "\n|%s| Text |%s| Boundary |BOUNDARY_LINE_START|\n",
+ type, text);
+ else if (boundary == ATK_TEXT_BOUNDARY_LINE_END)
+ sprintf(output, "\n|%s| Text |%s| Boundary |BOUNDARY_LINE_END|\n",
+ type, text);
+ else
+ sprintf(output, "\n|%s| Text |%s| Boundary |UNKNOWN|\n",
+ type, text);
+
+ g_free (text);
+ set_output_buffer(output);
+
+ sprintf(output, "Offset %d, startOffset %d, endOffset %d\n",
+ offset, startOffset, endOffset);
+ set_output_buffer(output);
+}
--- /dev/null
+#include <stdio.h>
+#include <gtk/gtk.h>
+#include <atk/atk.h>
+#include "testlib.h"
+
+void add_handlers (AtkObject *obj);
+gint setup_gui (AtkObject *obj, TLruntest test);
+void runtest(AtkObject *obj, gint win_num);
+void _run_offset_test(AtkObject *obj, char * type, gint param_int1, AtkTextBoundary boundary);
+void _notify_caret_handler (GObject *obj, int position);
+void _notify_text_insert_handler (GObject *obj,
+ int start_offset, int end_offset);
+void _notify_text_delete_handler (GObject *obj,
+ int start_offset, int end_offset);
+
--- /dev/null
+#include <atk/atk.h>
+#include <atk/atkvalue.h>
+#include <gtk/gtk.h>
+#include "testlib.h"
+
+static void _notify_toplevel_child_added (GObject *obj,
+ guint index, AtkObject *child, gpointer user_data);
+static void _notify_toplevel_child_removed (GObject *obj,
+ guint index, AtkObject *child, gpointer user_data);
+static gboolean _button_press_event_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values, const GValue *param_values, gpointer data);
+
+static guint id;
+static gboolean g_register_listener = FALSE;
+static guint g_signal_listener = 0;
+static gint g_press_count = 0;
+
+static void
+_check_toplevel (AtkObject *obj)
+{
+ AtkObject *root_obj;
+ const gchar *name_string, *version_string;
+ gint max_depth;
+
+ g_print ("Start of _check_toplevel\n");
+ root_obj = atk_get_root();
+
+ if (!already_accessed_atk_object(root_obj))
+ {
+ g_signal_connect_closure (root_obj, "children_changed::add",
+ g_cclosure_new (G_CALLBACK (_notify_toplevel_child_added),
+ NULL, NULL),
+ FALSE);
+
+ g_signal_connect_closure (root_obj, "children_changed::remove",
+ g_cclosure_new (G_CALLBACK (_notify_toplevel_child_removed),
+ NULL, NULL),
+ FALSE);
+ }
+
+ name_string = atk_get_toolkit_name();
+ version_string = atk_get_toolkit_version();
+ g_print ("Toolkit name <%s> version <%s>\n", name_string,
+ version_string);
+
+ if (g_getenv("TEST_ACCESSIBLE_DEPTH") != NULL)
+ max_depth = string_to_int(g_getenv("TEST_ACCESSIBLE_DEPTH"));
+ else
+ max_depth = 2;
+
+ display_children_to_depth(root_obj, max_depth, 0, 0);
+ g_print ("End of _check_toplevel\n");
+
+ if (!g_register_listener)
+ {
+ g_print("Adding global event listener on buttons\n");
+ g_register_listener = TRUE;
+ g_signal_listener = atk_add_global_event_listener(_button_press_event_watcher,
+ "Gtk:GtkButton:pressed");
+ }
+}
+
+static void
+_create_event_watcher (void)
+{
+ id = atk_add_focus_tracker (_check_toplevel);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testtoplevel Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
+
+static void _notify_toplevel_child_added (GObject *obj,
+ guint child_index, AtkObject *child, gpointer user_data)
+{
+ g_print ("SIGNAL - Child added - index %d\n", child_index);
+}
+
+static void _notify_toplevel_child_removed (GObject *obj,
+ guint child_index, AtkObject *child, gpointer user_data)
+{
+ g_print ("SIGNAL - Child removed - index %d\n", child_index);
+}
+
+static gboolean
+_button_press_event_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GObject *object;
+ gchar * button_name = (gchar *) data;
+
+ object = g_value_get_object (param_values + 0);
+
+ if (ATK_IS_IMPLEMENTOR(object))
+ {
+ AtkObject * atk_obj =
+ atk_implementor_ref_accessible(ATK_IMPLEMENTOR(object));
+
+ g_print("Button <%s> pressed %d times!\n", button_name,
+ (g_press_count + 1));
+ g_print("Displaying children of Button pressed!\n");
+ display_children(atk_obj, 0, 0);
+
+ if (g_press_count >= 5)
+ {
+ g_print("Removing global event listener on buttons\n");
+ atk_remove_global_event_listener(g_signal_listener);
+ g_signal_listener = 0;
+ g_press_count = 0;
+ g_register_listener = FALSE;
+ }
+ else
+ {
+ g_press_count++;
+ }
+ }
+
+ return TRUE;
+}
+
--- /dev/null
+#include <stdlib.h>
+#include <testlib.h>
+
+/*
+ * This module is for use with the test program testtreeview
+ */
+static gboolean state_change_watch (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data);
+
+static void _check_table (AtkObject *in_obj);
+static void _check_cell_actions (AtkObject *in_obj);
+
+static gint _find_expander_column (AtkTable *table);
+static void _check_expanders (AtkTable *table,
+ gint expander_column);
+static void _runtest (AtkObject *obj);
+static void _create_event_watcher (void);
+static void row_inserted (AtkObject *obj,
+ gint row,
+ gint count);
+static void row_deleted (AtkObject *obj,
+ gint row,
+ gint count);
+static AtkObject *table_obj = NULL;
+static gint expander_column = -1;
+static gboolean editing_cell = FALSE;
+
+static gboolean
+state_change_watch (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GObject *object;
+ gboolean state_set;
+ G_CONST_RETURN gchar *state_name;
+ AtkStateType state_type;
+
+ object = g_value_get_object (param_values + 0);
+ g_return_val_if_fail (ATK_IS_OBJECT (object), FALSE);
+
+ state_name = g_value_get_string (param_values + 1);
+ state_set = g_value_get_boolean (param_values + 2);
+
+ g_print ("Object type: %s state: %s set: %d\n",
+ g_type_name (G_OBJECT_TYPE (object)), state_name, state_set);
+ state_type = atk_state_type_for_name (state_name);
+ if (state_type == ATK_STATE_EXPANDED)
+ {
+ AtkObject *parent = atk_object_get_parent (ATK_OBJECT (object));
+
+ if (ATK_IS_TABLE (parent))
+ _check_expanders (ATK_TABLE (parent), expander_column);
+ }
+ return TRUE;
+}
+
+static void
+_check_table (AtkObject *in_obj)
+{
+ AtkObject *obj;
+ AtkRole role[2];
+ AtkRole obj_role;
+ static gboolean emission_hook_added = FALSE;
+
+ if (!emission_hook_added)
+ {
+ emission_hook_added = TRUE;
+ g_signal_add_emission_hook (
+ g_signal_lookup ("state-change", ATK_TYPE_OBJECT),
+ /*
+ * To specify an emission hook for a particular state, e.g.
+ * ATK_STATE_EXPANDED, instead of 0 use
+ * g_quark_from_string (atk_state_type_get_name (ATK_STATE_EXPANDED))
+ */
+ 0,
+ state_change_watch, NULL, (GDestroyNotify) NULL);
+ }
+
+ role[0] = ATK_ROLE_TABLE;
+ role[1] = ATK_ROLE_TREE_TABLE;
+
+ g_print ("focus event for: %s\n", g_type_name (G_OBJECT_TYPE (in_obj)));
+
+ _check_cell_actions (in_obj);
+
+ obj_role = atk_object_get_role (in_obj);
+ if (obj_role == ATK_ROLE_TABLE_CELL)
+ obj = atk_object_get_parent (in_obj);
+ else
+ obj = find_object_by_role (in_obj, role, 2);
+ if (obj == NULL)
+ return;
+
+ editing_cell = FALSE;
+
+ if (obj != table_obj)
+ {
+ table_obj = obj;
+ g_print("Found %s table\n", g_type_name (G_OBJECT_TYPE (obj)));
+ g_signal_connect (G_OBJECT (obj),
+ "row_inserted",
+ G_CALLBACK (row_inserted),
+ NULL);
+ g_signal_connect (G_OBJECT (obj),
+ "row_deleted",
+ G_CALLBACK (row_deleted),
+ NULL);
+ /*
+ * Find expander column
+ */
+ if (ATK_IS_TABLE (obj))
+ {
+ if (atk_object_get_role (obj) == ATK_ROLE_TREE_TABLE)
+ {
+ expander_column = _find_expander_column (ATK_TABLE (obj));
+ if (expander_column == -1)
+ {
+ g_warning ("Expander column not found\n");
+ return;
+ }
+ }
+ _runtest(obj);
+ }
+ else
+ g_warning ("Table does not support AtkTable interface\n");
+ }
+ else
+ {
+ /*
+ * We do not call these functions at the same time as we set the
+ * signals as the GtkTreeView may not be displayed yet.
+ */
+ gint x, y, width, height, first_x, last_x, last_y;
+ gint first_row, last_row, first_column, last_column;
+ gint index;
+ AtkObject *first_child, *last_child, *header;
+ AtkComponent *component = ATK_COMPONENT (obj);
+ AtkTable *table = ATK_TABLE (obj);
+
+ atk_component_get_extents (component,
+ &x, &y, &width, &height, ATK_XY_WINDOW);
+ g_print ("WINDOW: x: %d y: %d width: %d height: %d\n",
+ x, y, width, height);
+ atk_component_get_extents (component,
+ &x, &y, &width, &height, ATK_XY_SCREEN);
+ g_print ("SCREEN: x: %d y: %d width: %d height: %d\n",
+ x, y, width, height);
+ last_x = x + width - 1;
+ last_y = y + height - 1;
+ first_x = x;
+ header = atk_table_get_column_header (table, 0);
+ if (header)
+ {
+ atk_component_get_extents (ATK_COMPONENT (header),
+ &x, &y, &width, &height, ATK_XY_SCREEN);
+ g_print ("Got column header: x: %d y: %d width: %d height: %d\n",
+ x, y, width, height);
+ y += height;
+ }
+ first_child = atk_component_ref_accessible_at_point (component,
+ first_x, y, ATK_XY_SCREEN);
+ atk_component_get_extents (ATK_COMPONENT (first_child),
+ &x, &y, &width, &height, ATK_XY_SCREEN);
+ g_print ("first_child: x: %d y: %d width: %d height: %d\n",
+ x, y, width, height);
+ index = atk_object_get_index_in_parent (ATK_OBJECT (first_child));
+ first_row = atk_table_get_row_at_index (table, index);
+ first_column = atk_table_get_column_at_index (table, index);
+ g_print ("first_row: %d first_column: %d index: %d\n",
+ first_row, first_column, index);
+ g_assert (index == atk_table_get_index_at (table, first_row, first_column));
+ last_child = atk_component_ref_accessible_at_point (component,
+ last_x, last_y, ATK_XY_SCREEN);
+ if (last_child == NULL)
+ {
+ /* The TreeView may be bigger than the data */
+ gint n_children;
+
+ n_children = atk_object_get_n_accessible_children (obj);
+ last_child = atk_object_ref_accessible_child (obj, n_children - 1);
+ }
+ atk_component_get_extents (ATK_COMPONENT (last_child),
+ &x, &y, &width, &height, ATK_XY_SCREEN);
+ g_print ("last_child: x: %d y: %d width: %d height: %d\n",
+ x, y, width, height);
+ index = atk_object_get_index_in_parent (ATK_OBJECT (last_child));
+ last_row = atk_table_get_row_at_index (table, index);
+ last_column = atk_table_get_column_at_index (table, index);
+ g_print ("last_row: %d last_column: %d index: %d\n",
+ last_row, last_column, index);
+ g_assert (index == atk_table_get_index_at (table, last_row, last_column));
+ g_object_unref (first_child);
+ g_object_unref (last_child);
+
+ if (expander_column >= 0)
+ {
+ gint n_rows, i;
+ gint x, y, width, height;
+
+ n_rows = atk_table_get_n_rows (table);
+ for (i = 0; i < n_rows; i++)
+ {
+ AtkObject *child_obj;
+ AtkStateSet *state_set;
+ gboolean showing;
+
+ child_obj = atk_table_ref_at (table, i, expander_column);
+ state_set = atk_object_ref_state_set (child_obj);
+ showing = atk_state_set_contains_state (state_set,
+ ATK_STATE_SHOWING);
+ g_object_unref (state_set);
+ atk_component_get_extents (ATK_COMPONENT (child_obj),
+ &x, &y, &width, &height,
+ ATK_XY_SCREEN);
+ g_object_unref (child_obj);
+ if (showing)
+ g_print ("Row: %d Column: %d x: %d y: %d width: %d height: %d\n",
+ i, expander_column, x, y, width, height);
+ }
+ }
+ }
+}
+
+static void
+_check_cell_actions (AtkObject *in_obj)
+{
+ AtkRole role;
+ AtkAction *action;
+ gint n_actions, i;
+
+ role = atk_object_get_role (in_obj);
+ if (role != ATK_ROLE_TABLE_CELL)
+ return;
+
+ if (!ATK_IS_ACTION (in_obj))
+ return;
+
+ if (editing_cell)
+ return;
+
+ action = ATK_ACTION (in_obj);
+
+ n_actions = atk_action_get_n_actions (action);
+
+ for (i = 0; i < n_actions; i++)
+ {
+ G_CONST_RETURN gchar* name;
+
+ name = atk_action_get_name (action, i);
+ g_print ("Action %d is %s\n", i, name);
+#if 0
+ if (strcmp (name, "edit") == 0)
+ {
+ editing_cell = TRUE;
+ atk_action_do_action (action, i);
+ }
+#endif
+ }
+ return;
+}
+
+static gint
+_find_expander_column (AtkTable *table)
+{
+ gint n_columns, i;
+ gint retval = -1;
+
+ n_columns = atk_table_get_n_columns (table);
+ for (i = 0; i < n_columns; i++)
+ {
+ AtkObject *cell;
+ AtkRelationSet *relation_set;
+
+ cell = atk_table_ref_at (table, 0, i);
+ relation_set = atk_object_ref_relation_set (cell);
+ if (atk_relation_set_contains (relation_set,
+ ATK_RELATION_NODE_CHILD_OF))
+ retval = i;
+ g_object_unref (relation_set);
+ g_object_unref (cell);
+ if (retval >= 0)
+ break;
+ }
+ return retval;
+}
+
+static void
+_check_expanders (AtkTable *table,
+ gint expander_column)
+{
+ gint n_rows, i;
+
+ n_rows = atk_table_get_n_rows (table);
+
+ for (i = 0; i < n_rows; i++)
+ {
+ AtkObject *cell;
+ AtkRelationSet *relation_set;
+ AtkRelation *relation;
+ GPtrArray *target;
+ gint j;
+
+ cell = atk_table_ref_at (table, i, expander_column);
+
+ relation_set = atk_object_ref_relation_set (cell);
+ relation = atk_relation_set_get_relation_by_type (relation_set,
+ ATK_RELATION_NODE_CHILD_OF);
+ g_assert (relation);
+ target = atk_relation_get_target (relation);
+ g_assert (target->len == 1);
+ for (j = 0; j < target->len; j++)
+ {
+ AtkObject *target_obj;
+ AtkRole role;
+ gint target_index, target_row;
+
+ target_obj = g_ptr_array_index (target, j);
+ role = atk_object_get_role (target_obj);
+
+ switch (role)
+ {
+ case ATK_ROLE_TREE_TABLE:
+ g_print ("Row %d is top level\n", i);
+ break;
+ case ATK_ROLE_TABLE_CELL:
+ target_index = atk_object_get_index_in_parent (target_obj);
+ target_row = atk_table_get_row_at_index (table, target_index);
+ g_print ("Row %d has parent at %d\n", i, target_row);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ }
+ g_object_unref (relation_set);
+ g_object_unref (cell);
+ }
+}
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_check_table);
+}
+
+int
+gtk_module_init (gint argc,
+ char *argv[])
+{
+ g_print ("testtreetable Module loaded\n");
+
+ _create_event_watcher ();
+
+ return 0;
+}
+
+static void
+_runtest (AtkObject *obj)
+{
+ AtkObject *child_obj;
+ AtkTable *table;
+ AtkObject *caption;
+ gint i;
+ gint n_cols, n_rows, n_children;
+
+ table = ATK_TABLE (obj);
+ n_children = atk_object_get_n_accessible_children (ATK_OBJECT (obj));
+ n_cols = atk_table_get_n_columns (table);
+ n_rows = atk_table_get_n_rows (table);
+ g_print ("n_children: %d n_rows: %d n_cols: %d\n",
+ n_children, n_rows, n_cols);
+
+ for (i = 0; i < n_rows; i++)
+ {
+ gint index = atk_table_get_index_at (table, i, expander_column);
+ gint index_in_parent;
+
+ child_obj = atk_table_ref_at (table, i, expander_column);
+ index_in_parent = atk_object_get_index_in_parent (child_obj);
+ g_print ("index: %d %d row %d column %d\n", index, index_in_parent, i, expander_column);
+
+ g_object_unref (child_obj);
+ }
+ caption = atk_table_get_caption (table);
+ if (caption)
+ {
+ const gchar *caption_name = atk_object_get_name (caption);
+
+ g_print ("Caption: %s\n", caption_name ? caption_name : "<null>");
+ }
+ for (i = 0; i < n_cols; i++)
+ {
+ AtkObject *header;
+
+ header = atk_table_get_column_header (table, i);
+ g_print ("Header for column %d is %p\n", i, header);
+ if (header)
+ {
+ const gchar *name;
+ AtkRole role;
+ AtkObject *parent;
+ AtkObject *child;
+ gint index;
+
+ name = atk_object_get_name (header);
+ role = atk_object_get_role (header);
+ parent = atk_object_get_parent (header);
+
+ if (parent)
+ {
+ index = atk_object_get_index_in_parent (header);
+ g_print ("Parent: %s index: %d\n", G_OBJECT_TYPE_NAME (parent), index);
+ child = atk_object_ref_accessible_child (parent, 0);
+ g_print ("Child: %s %p\n", G_OBJECT_TYPE_NAME (child), child);
+ if (index >= 0)
+ {
+ child = atk_object_ref_accessible_child (parent, index);
+ g_print ("Index: %d child: %s\n", index, G_OBJECT_TYPE_NAME (child));
+ g_object_unref (child);
+ }
+ }
+ else
+ g_print ("Parent of header is NULL\n");
+ g_print ("%s %s %s\n", G_OBJECT_TYPE_NAME (header), name ? name: "<null>", atk_role_get_name (role));
+ }
+ }
+}
+
+static void
+row_inserted (AtkObject *obj,
+ gint row,
+ gint count)
+{
+#if 0
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GtkTreeModel *tree_model;
+#endif
+ gint index;
+
+ g_print ("row_inserted: row: %d count: %d\n", row, count);
+ index = atk_table_get_index_at (ATK_TABLE (obj), row+1, 0);
+ g_print ("index for first column of next row is %d\n", index);
+
+#if 0
+ widget = GTK_ACCESSIBLE (obj)->widget;
+ tree_view = GTK_TREE_VIEW (widget);
+ tree_model = gtk_tree_view_get_model (tree_view);
+ if (GTK_IS_TREE_STORE (tree_model))
+ {
+ GtkTreeStore *tree_store;
+ GtkTreePath *tree_path;
+ GtkTreeIter tree_iter;
+
+ tree_store = GTK_TREE_STORE (tree_model);
+ tree_path = gtk_tree_path_new_from_string ("3:0");
+ gtk_tree_model_get_iter (tree_model, &tree_iter, tree_path);
+ gtk_tree_path_free (tree_path);
+ gtk_tree_store_remove (tree_store, &tree_iter);
+ }
+#endif
+}
+
+static void
+row_deleted (AtkObject *obj,
+ gint row,
+ gint count)
+{
+#if 0
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GtkTreeModel *tree_model;
+#endif
+ gint index;
+
+ g_print ("row_deleted: row: %d count: %d\n", row, count);
+ index = atk_table_get_index_at (ATK_TABLE (obj), row+1, 0);
+ g_print ("index for first column of next row is %d\n", index);
+
+#if 0
+ widget = GTK_ACCESSIBLE (obj)->widget;
+ tree_view = GTK_TREE_VIEW (widget);
+ tree_model = gtk_tree_view_get_model (tree_view);
+ if (GTK_IS_TREE_STORE (tree_model))
+ {
+ GtkTreeStore *tree_store;
+ GtkTreePath *tree_path;
+ GtkTreeIter tree_iter, new_iter;
+
+ tree_store = GTK_TREE_STORE (tree_model);
+ tree_path = gtk_tree_path_new_from_string ("2");
+ gtk_tree_model_get_iter (tree_model, &tree_iter, tree_path);
+ gtk_tree_path_free (tree_path);
+ gtk_tree_store_insert_before (tree_store, &new_iter, NULL, &tree_iter);
+ }
+#endif
+}
--- /dev/null
+#include <string.h>
+#include <atk/atk.h>
+#include <atk/atkvalue.h>
+#include <gtk/gtk.h>
+
+static void _traverse_children (AtkObject *obj);
+static void _add_handler (AtkObject *obj);
+static void _check_values (AtkObject *obj);
+static void _value_change_handler (AtkObject *obj,
+ AtkPropertyValues *values);
+
+static guint id;
+
+static void _value_change_handler (AtkObject *obj,
+ AtkPropertyValues *values)
+{
+ G_CONST_RETURN gchar *type_name = g_type_name (G_TYPE_FROM_INSTANCE (obj));
+ GValue *value_back, val;
+
+ value_back = &val;
+
+ if (!ATK_IS_VALUE (obj)) {
+ return;
+ }
+
+ if (strcmp (values->property_name, "accessible-value") == 0) {
+ g_print ("_value_change_handler: Accessible Type: %s\n",
+ type_name ? type_name : "NULL");
+ if(G_VALUE_HOLDS_DOUBLE (&values->new_value))
+ {
+ g_print( "adjustment value changed : new value: %f\n",
+ g_value_get_double (&values->new_value));
+ }
+
+ g_print("Now calling the AtkValue interface functions\n");
+
+ atk_value_get_current_value (ATK_VALUE(obj), value_back);
+ g_return_if_fail (G_VALUE_HOLDS_DOUBLE (value_back));
+ g_print ("atk_value_get_current_value returns %f\n",
+ g_value_get_double (value_back) );
+
+ atk_value_get_maximum_value (ATK_VALUE (obj), value_back);
+ g_return_if_fail (G_VALUE_HOLDS_DOUBLE (value_back));
+ g_print ("atk_value_get_maximum returns %f\n",
+ g_value_get_double (value_back));
+
+ atk_value_get_minimum_value (ATK_VALUE (obj), value_back);
+ g_return_if_fail (G_VALUE_HOLDS_DOUBLE (value_back));
+ g_print ("atk_value_get_minimum returns %f\n",
+ g_value_get_double (value_back));
+
+
+ }
+
+}
+
+static void _traverse_children (AtkObject *obj)
+{
+ gint n_children, i;
+
+ n_children = atk_object_get_n_accessible_children (obj);
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject *child;
+
+ child = atk_object_ref_accessible_child (obj, i);
+ _add_handler (child);
+ _traverse_children (child);
+ g_object_unref (G_OBJECT (child));
+ }
+}
+
+static void _add_handler (AtkObject *obj)
+{
+ static GPtrArray *obj_array = NULL;
+ gboolean found = FALSE;
+ gint i;
+
+ /*
+ * We create a property handler for each object if one was not associated
+ * with it already.
+ *
+ * We add it to our array of objects which have property handlers; if an
+ * object is destroyed it remains in the array.
+ */
+ if (obj_array == NULL)
+ obj_array = g_ptr_array_new ();
+
+ for (i = 0; i < obj_array->len; i++)
+ {
+ if (obj == g_ptr_array_index (obj_array, i))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found)
+ {
+ atk_object_connect_property_change_handler (obj,
+ (AtkPropertyChangeHandler*) _value_change_handler);
+ g_ptr_array_add (obj_array, obj);
+ }
+}
+
+static void _set_values (AtkObject *obj) {
+
+ GValue *value_back, val;
+ static gint count = 0;
+ gdouble double_value;
+
+ value_back = &val;
+
+ if(ATK_IS_VALUE(obj)) {
+ /* Spin button also inherits the text interfaces from GailEntry.
+ * Check when spin button recieves focus.
+ */
+
+ if(ATK_IS_TEXT(obj) && ATK_IS_EDITABLE_TEXT(obj)) {
+ if(count == 0) {
+ gint x;
+ gchar* text;
+ count++;
+ x = atk_text_get_character_count (ATK_TEXT (obj));
+ text = atk_text_get_text (ATK_TEXT (obj), 0, x);
+ g_print("Text : %s\n", text);
+ text = "5.7";
+ atk_editable_text_set_text_contents(ATK_EDITABLE_TEXT(obj),text);
+ g_print("Set text to %s\n",text);
+ atk_value_get_current_value(ATK_VALUE(obj), value_back);
+ g_return_if_fail (G_VALUE_HOLDS_DOUBLE (value_back));
+ g_print("atk_value_get_current_value returns %f\n",
+ g_value_get_double( value_back));
+ }
+ } else {
+ memset (value_back, 0, sizeof (GValue));
+ g_value_init (value_back, G_TYPE_DOUBLE);
+ g_value_set_double (value_back, 10.0);
+ if (atk_value_set_current_value (ATK_VALUE (obj), value_back))
+ {
+ double_value = g_value_get_double (value_back);
+ g_print("atk_value_set_current_value returns %f\n",
+ double_value);
+ }
+ }
+ }
+}
+
+static void _check_values (AtkObject *obj)
+{
+ static gint calls = 0;
+ AtkRole role;
+
+ g_print ("Start of _check_values\n");
+
+ _set_values(obj);
+
+ _add_handler (obj);
+
+ if (++calls < 2)
+ {
+ /*
+ * Just do this on this on the first 2 objects visited
+ */
+ atk_object_set_name (obj, "test123");
+ atk_object_set_description (obj, "test123");
+ }
+
+ role = atk_object_get_role (obj);
+
+ if (role == ATK_ROLE_FRAME || role == ATK_ROLE_DIALOG)
+ {
+ /*
+ * Add handlers to all children.
+ */
+ _traverse_children (obj);
+ }
+ g_print ("End of _check_values\n");
+}
+
+static void
+_create_event_watcher (void)
+{
+ id = atk_add_focus_tracker (_check_values);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testvalues Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}